Custom services

Custom services

ubuntu 18.04 hw2018 systemd

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.