The simplest method I've found for starting a persistent background service via systemd, which may be handy since you can then get it to report on subprocesses currently running as children via
systemctl status ..., etc., is via a service file like this:
Description will appear in the system log and boot console output.
You almost certainly want at least that
After=rsyslog is not a necessity, and
After itself differs from
Requires in that the latter is an explicit dependency, whereas
After just means if
rsyslog.service is being run, start this afterward (see
man systemd.unit). Pretty sure Raspbian does use that by default, so this is not a bad thing to have and harmless in any case.
Type=forking and the two next two lines are important.
myservice is capable of backgrounding itself, e.g., via a commandline parameter, you could specify it here. However, IMO using
wrapperScript is simpler and more flexible; keep reading.
wrapperScript.sh might look like:
echo $(date +"%D %T")" Starting..."
( exec /absolute/path/to/myservice -port :1234 &>>$log ) &
&>> is a bashism meaning append redirect all output (standard and error). If you want to overwrite the log each time, make the first use
You can set
$PATH however you like, just beware it probably won't be set to anything by default, at least when this is started at boot by systemd.
The reason to redirect output to a log from the beginning, and output "Starting..." (actually it will look like
08/02/16 15:25:29 Starting...) is in case something subsequently doesn't work out; you can at least confirm you got to this point. Note that when run at boot on a Pi without an RTC the timestamp won't be valid unless
ntpd has already done its work, which is unlikely. And there's no dependency available for the time being set right via ntp as far as I'm aware, so don't bother trying.
The format of the subshell
exec and fork (
&) is important. This ensures that your process replaces the shell instead of being run within it (actually that isn't that important, but it is tidier) and that this service fulfills the promise made in the service file, vis.
Type=forking. Which is critical.
The exit status doesn't mean systemd will assume the service has executed successfully; if a child process (
myservice) then exits with a non-zero status, it will count as failed.
I use this pattern with all kinds of things and for me, it is the simplest, most foolproof and flexible method without having to rely too much on subtleties of systemd features. Put another way, there is no doubt a more proper way, from a systemd usage perspective, to get more-or-less the same result, but for that you'll have to spend some time delving through the documentation, experimenting, and hoping your assumptions are correct. By instead using a simple shell controlled fork, we take the power back so to speak.
BTW (includes a few caveats):
You don't have to install this to run at boot in order to use it. Just leave a copy of the service file owned root in
/etc/systemd/system with the suffix
sudo systemctl daemon-reload, and you can then use
systemctl start whatever to run it and
systemctl status whatever to check on it.
If you do want to install it to run at boot, use
sudo systemctl enable whatever and it will be included in
This doesn't include any kind of "stop" behaviour. The process will be politely killed at shutdown/reboot which is fine for most things. If you want to stop
sudo kill it. It doesn't include any kind of restart either, hopefully you can figure out the logic for that.