Giving argument to systemd binary

Posted on

Problem :

I am trying to run a systemd service for my binary. The binary expects an argument for –public-ip field, which i supply through curl https://ipinfo.io/ip. I did in the following way but the executable is not getting started correctly.

When I checked with sudo journalctl -f , i saw that the binary cant see the argument supplied to –public-ip option, so it is hanging in a loop continuously trying. WHen I call the exact same command from the terminal it seems to work.

What am i missing here ?

I am on 20.04 Ubuntu server

[Unit]
Description=test node
After=network.target
StartLimitIntervalSec=0
[Service]
Type=simple
Restart=always
RestartSec=1
User=$(whoami)
ExecStart='/my/working/directory/binary --public-ip "$(curl https://ipinfo.io/ip)"'
[Install]
WantedBy=multi-user.target

Solution :

systemd does its own minimalistic shell-style command line parsing of the contents of ExecStart= and other parameters. Command substitution ($()) is not supported. You
need an actual shell to handle $(curl https://ipinfo.io/ip).

ExecStart=/bin/sh -c 'exec /my/working/directory/binary --public-ip "$(curl https://ipinfo.io/ip)"'

Notes:

  • The shell may be able to locate curl via the default $PATH; if not, then use /full/path/to/curl or expand $PATH.
  • After the shell handles $(), it will replace itself with your binary thanks to exec. This way you can still use Type=simple (not Type=forking).
  • You may find SyslogIdentifier=foo useful (see this answer).

Leave a Reply

Your email address will not be published. Required fields are marked *