systemd is the glue that holds Linux systems together.
systemd is a collection of building blocks, which handle services, processes, logging, network connectivity and even authentication. In this article, I will show you how to work with services in
What exactly is
systemd is a suite of computer programs aimed to manage and interconnect different parts of system together. It is designed as a replacement for SystemV and LSB-style startup scrips, which were prevalent since 1980s.
systemd consists of these components:
systemd, which is the system and service manager
systemctl, a command line tool to interact with
journald, a unified logging framework
logind, a daemon that handles user logins and seats
networkd, which are responsible for network connection, domain name resolution and synchronizing time with internet resources
This is a very high-level overview of
systemd‘s architecture, but will suit us for now.
Managing existing services
A service is essentially a process, running in the background and managed/provisioned by
systemd. Stuff you would like to run as services includes various servers (HTTP, SSH, FTP), synchronization utilities (Syncthing,
rsync), virtualisation hypervisors (Docker, K8s), and many more. Let’s start by listing all available services on your system by running this command:
You will be presented with a table that looks like this:
By default, this command will list devices, mount points, namespaces, and services, which we are interested it. Scroll down to see the service section (you will notice everything having a
Here is the structure of this table:
- Name of the service. (Matches the name of the
- Current status of the service.
systemdknows about it,
systemdran it successfully
- Current status of the process. It indicates if the process is
exited. Note that an
activeservice can be
exited(for example, 1 action has to happen at boot, and the process than returns. The service is still considered
If you want to see some more details of a specific service, use this command:
$ systemctl status SERVICE_NAME
For example, running
systemctl status dbus on my system will produce the following:
This command will tell you more info than the previous some, for example the uptime, the path to
.service file, the process name and its
PID. While this is helpful,
status is usually used to troubleshoot a service. For example, I have a problem with a service
syncthing-discosrv. Running the same command on it will tell me this:
You can notice the logs, conveniently printed at the end. This tells me precisely what when wrong when
systemd tried to start this service and I can now fix that easily.
Lastly, the most interesting commands. To start/stop services, use this:
$ systemctl start/stop SERVICE_NAME
Similarly, you can enable or disable the services. Enabled means it will run on boot:
$ systemctl enable/disable SERVICE_NAME
Now, to the interesting part.
Creating your own services
systemd won’t be very useful if it did not let you create your own services. Thankfully, this is quite easy to do. Let’s start with the most basic example: running a
bash script on boot. Suppose you have a script, located at
/usr/bin/runme.sh that does some sort of cleanup. Now, to run it on boot, you need to create a unit file. Create it in
[Unit] Description=Cleaning service [Service] Type=simple ExecStart=/bin/bash /usr/bin/runme.sh [Install] WantedBy=multi-user.target
This should be pretty straightforward. The
Description sets the description (as seen earlier in the article).
Type sets the type of our service, which can also be
forking, if service spawns multiple processes.
ExecStart is the actual command used to run the service. Lastly, the
WantedBy specifies when this service should run.
multi-user means regulal system startup and what you want most of the time. Note that if you start in single-user mode (recovery), this service would not run (which may or may not be what you want). Now, to enable this service:
$ systemctl enable runme $ systemctl status runme // .... ENABLED .....
If you want, you can also run it once right now:
$ systemctl start runme
Now, let’s consider a slightly more sophisticated example. Suppose you have a Python script (located at
/etc/scripts/server.py) that must be run at boot, but after network is up. Also, you want it to restart on crash, but not too often. If this sounds like your case, use something like this for your service file:
[Unit] Description=My awesome service After=network.target [Service] type=Simple User=username Restart=on-failure RestartSec=1 StartLimitBurst=5 StartLimitIntervalSec=10 StartLimitAction=reboot ExecStart=/bin/python /etc/scripts/server.py [Install] WantedBy=multi-user.target
Quite a few new options here. The
After directive specifies this service’s dependency on
network target, which initializes network connectivity. Later, we specify the
User to run the script as
username. Now, there are 5(!) options to control the resilience of our service.
Restart specifies when the service is to be restarted.
RestartSec will not let
systemd restart more than once a second.
StartLimitIntervalSec say that service can be restarted at most 5 times in a 10 second interval. Lastly,
StartLimitAction asks to reboot the system if the service still fails after all those restats. Obviously, this is not advised if there are many vital services on your machine. Once set up, you can enable and start this service just like the rest of them.
Thank you for reading, I hope you liked this article. Please let me know your opinion about
systemd, I hear there is quite a lot of controversy there.