Systemd service syntax
Documentation
All config opts https://www.freedesktop.org/software/systemd/man/systemd.directives.html man systemd.unit
https://man.archlinux.org/man/core/systemd/systemd.unit.5.en man systemd.service
https://man.archlinux.org/man/core/systemd/systemd.service.5.en man systemd.target
https://man.archlinux.org/man/systemd.target.5
Locations
/etc/systemd/{user,system}/*.service
systemwide user/system unitfiles /usr/lib/systemd/{user,system}/*.service
package user/system unitfiles ~/.config/systemd/user/*.service
user unitfiles
Tutorials
archwiki: user services https://wiki.archlinux.org/title/Systemd/User
Example
[Unit] Description=Daemon to detect crashing apps Requires=display-manager.service network-online.target After=ctrl-alt-del.target [Service] ExecStart=/usr/sbin/abrtd Type=forking [Install] WantedBy=multi-user.target
Sections
[Unit]:
A service file will launch system services, devices, mount points and more. The word that encompasses all of these terms is unit. This section is where you write a description for the service, and also set the dependencies. There are two options for Dependencies:
- After= Script will not be launched until after this service is started
- Requires= Script will not be launched unless required service has been started.
You may have multiple dependencies for After and/or Requires, simply separate each service by a space. Here is a complete list of services that are triggered for special events like when the internet is connected, CTRL-ALT-DELETE is executed, or the start of a display manager. http://0pointer.de/public/systemd-man/systemd.special.html
You can find the order of execution of systemd services (units) with:
systemd --test --system | grep Unit | grep -[Unit] Description=Daemon to detect crashing apps Requires=display-manager.service network-online.target After=ctrl-alt-del.target[Service]
The service section is for information related to starting services only. Mount points, Devices, Timers etc do not need this section. There are two arguments here:
- ExecStart= links to the binary you want to run
- Type= defines the type of service that you would like
Your options for type are as follows:
simple let systemd manage the process, no fork() call required. (bash scripts, python scripts, ...) forking Traditional Init way. Process is forked to the background but listed as the main daemon process. you are apparently responsible for calling fork() yourself. oneshot Run Once, and Terminate before running next unit. dbus ??? notify Same as simple, except expects output to sd_notify when it has finished running. (notifies systemd when finished running) idle Waits for currently running jobs are dispatched to run (to not push info from multiple jobs to console) [Service] ExecStart=/usr/bin/python /some/script.py Environment='PYTHONPATH=/home/will/progs/python/general/projects:/home/will/progs/python/general:/home/will/progs/maya/m2014/pythonScriptLib' Environment='PIPELINE_PYTHONSTART=/home/will/.pythonrc' Type=simple[Install]
This install section determines what your service should wait for in order to run.
[Install] WantedBy=graphical.targetSome common targets:
graphical.target # after x11 starts bluetooth.target # after bluetooth starts network-online.target # wait until a routable ip address is up multi-user.target # immediately once graduating from single-user mode.
List all targets:ls -l /usr/lib/systemd/system/*.target
Configurable Services
Run As User
You can do this in 2x ways:
systemctl --user
You can do this with any service.
systemctl --user enable mpd.servicempd@user.service
You configure the user/group a systemd service runs as with the
User
andGroup
keys under the[Service]
Category.These can be made configurable with the
%I
value. In order to indicate this to your user, your service must be in the formatmyservice@.service
.[Service] User=%I Group=%I# You can then start your service by starting/enabling it with systemctl enable myservice@will.serviceConfigurable Variables
You can write configurable services using bash-like variables.
Then name combination of variable-values in/etc/default
# /etc/systemd/system/yourservice@.service [Service] ExecStart=${COMMAND} ${ARGS}# /etc/default/yourservice@echo-hi COMMAND=echo ARGS=hi # /etc/default/yourservice@echo-hello COMMAND=echo ARGS=hellosystemctl enable yourservice@echo-hello.serviceService Overrides
You can also override any service independent of the OS packages even if they are not designed to be customizable.
# creates /etc/systemd/system/myservice.service.d/override.conf systemctl edit myservice.service
Features
Auto Restarts
The following options together as used to configure service restart behaviour.
Note thatStartLimitIntervalSec
must be greater thanRestartSec * StartLimitBurst
.[Unit] # retry a max of 5 times within `StartLimitIntervalSec` StartLimitBurst=5 # Units started more than `StartLimitBurst` times # within `StartLimitIntervalSec` are not permitted to restart anymore StartLimitIntervalSec=200 [Service] # restart on non-zero exit-code Restart=on-failure # Time to sleep before restarting a service RestartSec=