The previous post was about services, now let’s evaluate custom services and some other ways to start a program at boot time, without user intervention.
A sample program
Since I don’t want this post to be too specific, here is a sample program, written only for testing automatic starting.
This program will write periodically it’s name, parameters, user, group, pid and parent pid.
Most command line programs write directly to stdout,
but since this one is intened to be run non-interactively, let’s use the system
logger.
#!/bin/bash
while true
do
logger "$0 pid:$$ ppid:$PPID user:$(id -un) group:$(id -g) parameters:'$@'"
sleep 60
done
Let’s save it to /bin/testservice and make it executable
sudo chmod +x /bin/testservice
Watching the result
In ubuntu the logger will write to /var/log/syslog, so for
the rest of this post, a second console is necessary for running this :
tail -f /var/log/syslog
Manual testing
Let’s just start the program by hand, just to verify what’s going on syslog.
pim@server:~$ testservice just testing the command line
CTRL-C
Result on syslog:
Jun 26 17:33:44 server pim: /bin/testservice pid:20232 ppid:1525 user:pim group:1000 parameters:'testing the command line'
Using /etc/rc.local (deprecated)
Even though ubuntu switched to systemd
years ago, it’s still possible to use /etc/rc.local to start a program at boot.
Edit (create) /etc/rc.local
#!/bin/sh -e
testservice from /etc/rc.local &
exit 0
Make it executable sudo chmod +x /etc/rc.local and reboot, result in syslog:
Jun 26 17:44:28 server root: /bin/testservice pid:938 ppid:1 user:root group:0 parameters:'from /etc/rc.local'
Stopping
Find the pid using ps ax | grep testservice, then sudo kill NUMBER
Disabling the script (won’t stop it)
Remove the /etc/rc.local file.
Using cron @reboot
Edit the crontab using crontab -e, the script will be run with the current user.
# Edit this file to introduce tasks to be run by cron.
#
# ...
#
# m h dom mon dow command
@reboot testservice from crontab @reboot &
Reboot to test, result in syslog:
Jun 26 18:00:03 server pim: /bin/testservice pid:893 ppid:1 user:pim group:1000 parameters:'from crontab @reboot'
Stopping
Find the pid using ps ax | grep testservice, then sudo kill NUMBER
Disabling the script (won’t stop it)
Remove the line using crontab -e.
Using a systemd (system) service
Create the /etc/systemd/system/testservice.service file :
[Unit]
Description=testservice
[Service]
ExecStart=/bin/testservice from a systemd service
[Install]
WantedBy=multi-user.target
After each edit, tell systemd to reload the file : sudo systemctl daemon-reload,
then enable and start the service:sudo systemctl enable testservice --now
Result in syslog:
Jun 26 18:19:40 server root: /bin/testservice pid:1513 ppid:1 user:root group:0 parameters:'from a systemd service'
Stopping
sudo sytemctl stop testservice
Disabling the script (won’t stop it)
sudo sytemctl disable testservice
Disabling and stopping the script
sudo sytemctl disable testservice --now
Running as a user
Create the ~/.config/systemd/user/testservice.service file:
[Unit]
Description=testservice
[Service]
ExecStart=/bin/testservice from a systemd service testing as a user
User=pim
Group=pim
[Install]
WantedBy=multi-user.target
Testing : sudo systemctl daemon-reload && sudo systemctl restart testservice,
result in syslog:
Jun 26 18:26:17 server pim: /bin/testservice pid:1662 ppid:1 user:pim group:1000 parameters:'from a systemd service as a user'
systemd provides a lot of options like automatic restart
in case of crash, onehsot service, and a lot more, see man systemd.service.
Using a systemd (user) service
Enable the systemd service for the user : sudo loginctl enable-linger pim
Create the directory mkdir -p ~/.config/systemd/user then the file ~/.config/systemd/user/testservice.service file :
[Unit]
Description=testservice
[Service]
ExecStart=/bin/testservice from a systemd user service
[Install]
WantedBy=default.target
Test it : systemctl --user daemon-reload && systemctl --user enable testservice --now, result in syslog:
Jun 26 19:15:17 server pim: /bin/testservice pid:2033 ppid:1077 user:pim group:1000 parameters:'from a systemd user service'
Starting/Stopping/…
The standard systemctl command can be used, without sudo but with --user.
Pros and cons of each method
| Method | Pros | Cons |
|---|---|---|
| /etc/rc.local | Simple | No simple way to start/stop/restart the service Deprecated |
| crontab @reboot | Simple No superuser action required |
No simple way to start/stop/restart the service |
| systemd system service | Standard (simple) start/stop/restart/status/… | Complexity |
| systemd user service | Standard (simple) start/stop/restart/status/… Superuser action only required once (for loginctl enable-linger) |
Complexity |
~~~
Question, remark, bug? Don't hesitate to contact me or report a bug.