Systemd Services 101
Tutorials – Systemd
Take control of the services running on your Linux machine
Systemd is the init system of almost all modern Linux distributions. It's the first process to start when Linux boots up, and it controls everything else that runs on your computer. Much of this happens automatically, and you should never have to think about it, but there are some bits that you may wish to poke around from time to time.
Before we get too far in, the first thing to do is check if you're using systemd. You can do so with the command:
pidof systemd
If this returns a number, then you're running on a systemd distro, if there's no output, then you're using some other init system. To follow along with this tutorial, you'll need systemd, so you may want to download a live distro such as Ubuntu and run it in a virtual environment.
I mentioned that systemd controls everything that runs on your computer. It does this through services, which are normal bits of software that systemd starts automatically at a predetermined point. For example, if you're using a desktop environment, systemd will launch your login manager once the graphical system has started. This login manager starts your desktop and your desktop starts your graphical software. You can see how everything branches out of systemd with the command:
pstree -p
Systemd decides what to launch by looking at the service files. If you're familiar with the old style SysVinit, these service files take the place of the init.d scripts, but they're a very different syntax.
Let's look at this by creating our own service. In general, services are bits of software that run indefinitely, and ours will be no different. It's a hello world service that just outputs "hello world" every 30 seconds (Figure 1). Create a text file called hws.sh
in your home directory with the following:
#!/bin/bash while $(sleep 30); do echo "hello world" done
Make this file executable with:
chmod a+x hws.sh
You can now run this from the command line with ./hws.sh
, but that's not running it as a service. Now let's look at how to get systemd to start this automatically every time you start your computer.
The service files are typically split into two sections, Unit and Service. The Unit section has the basic information about what this file is for and when to run it. The Service section contains details about what actually we want to run. A basic service file for our Hello World Service is:
[Unit] Description=Hello world service After=systemd-user-sessions.service [Service] Type=simple ExecStart=/home/ben/hws.sh
As you can see, this contains a description that can be anything you want. The After line tells systemd when to start this service by telling it what needs to be started before this one can. We're just waiting for the user sessions to start, although really, this could be started earlier if desired.
Setting Type
to simple
tells systemd that this is a command that will continue to run in the session it was started. The alternative here is Type=forking
, which is for commands that handle their own daemonization. You can think of this in terms of running something from the command line. If, when you run a command, it continues to send output to the terminal, it's a simple type, whereas if the commands kick of some background processes and return the command prompt, then it's a forking type. The final line here is just the command to run.
Save this in a file called hws.service
(the filename is important in this case), and then copy this file to /etc/systemd/system
(you may need to use sudo). Once this is in place, you can start the service with:
systemctl start hws.service
Once that's finished, your hello world service is running in the background greeting the rest of the planet. All the output from processes started like this is gobbled by another part of systemd: journald. You can view this with the command:
systemctl status hws
This will show you the last few log lines as well as information about the processes running. You can also view the entire log with:
journalctl -u hws -e
The -u
flag tells journalctl which unit (that is, service file) to show the output of, and the -e
flag means start from the end of the file and work backwards. By default, this will show the log in a scrollable environment, but if you pipe the command into something else (e.g., grep), then it will send the text to stdout.
Most distributions also send the output from systemd services to the syslog. This is an option in systemd rather than a fixed feature, and we may find that over time, this happens in fewer and fewer distros as people become used to working with journalctl rather than the logfiles.
Let's take a look at these journald lines. You should have seen something like this:
Apr 24 20:02:52 ben-desktop hws.sh[3790]: hello world Apr 24 20:03:22 ben-desktop hws.sh[3790]: hello world
Obviously, the first section is the date. The next item in the line is the machine that this happens on. Although it might initially seem obvious which machine it's running on, this isn't always the case as logs are often amalgamated into a centralized logging system. The next bit is the name of the software that's running and the process identifier. The final bit is the actual output.
Most of this output looks quite good, but the hws.sh
part isn't very clear. We could rename the file that runs, but we don't need to. Instead, we can just tell systemd to use something else in the logging. This is the syslog identifier. If you include the following line in the Service section of the hws.service
file, it will replace hws.sh
with something more meaningful:
SyslogIndentifier=HelloWorldService
We've only looked at the most basic options here, and there are many more advanced features. Most of them are as simple as setting options in the service file, and the process is well documented in the systemd.exec man page (Figure 2). See the "Systemd Timers" box for more information.
Systemd Timers
In this tutorial, we've looked at services that start and then continue to run. However, there's another type of background program: scheduled tasks. These we want to run periodically rather than constantly. You can use cron, but systemd provides tools for this. First, you need to create a service file as we have done in the main tutorial; then you need a timer file, which should have the same name as the service file but with the .timer
ending. This is saved in the same directory as the service file. A simple Timer file that would run our hello world service (even if it stopped running or didn't have a loop to continue to run) is:
[Unit] Description=Run HWS 30 mins after booting then every week [Timer] OnBootSec=30min OnUnitActiveSec=1w [Install] WantedBy=timers.target
As you can see, you can time relative to booting as well as on pre-defined periods.
Systemd has made it much easier to create services, especially for people not skilled in the dark art of Bash scripting. As you've seen, a simple service file isn't scary; it's just a place to tell systemd what you want to do. You should be able to take the skills we've covered in this tutorial and apply them to running almost any software as a service. Don't fear the daemon.
Buy this article as PDF
(incl. VAT)
Buy Linux Magazine
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs
Subscribe to our ADMIN Newsletters
Support Our Work
Linux Magazine content is made possible with support from readers like you. Please consider contributing when you’ve found an article to be beneficial.
News
-
Halcyon Creates Anti-Ransomware Protection for Linux
As more Linux systems are targeted by ransomware, Halcyon is stepping up its protection.
-
Valve and Arch Linux Announce Collaboration
Valve and Arch have come together for two projects that will have a serious impact on the Linux distribution.
-
Hacker Successfully Runs Linux on a CPU from the Early ‘70s
From the office of "Look what I can do," Dmitry Grinberg was able to get Linux running on a processor that was created in 1971.
-
OSI and LPI Form Strategic Alliance
With a goal of strengthening Linux and open source communities, this new alliance aims to nurture the growth of more highly skilled professionals.
-
Fedora 41 Beta Available with Some Interesting Additions
If you're a Fedora fan, you'll be excited to hear the beta version of the latest release is now available for testing and includes plenty of updates.
-
AlmaLinux Unveils New Hardware Certification Process
The AlmaLinux Hardware Certification Program run by the Certification Special Interest Group (SIG) aims to ensure seamless compatibility between AlmaLinux and a wide range of hardware configurations.
-
Wind River Introduces eLxr Pro Linux Solution
eLxr Pro offers an end-to-end Linux solution backed by expert commercial support.
-
Juno Tab 3 Launches with Ubuntu 24.04
Anyone looking for a full-blown Linux tablet need look no further. Juno has released the Tab 3.
-
New KDE Slimbook Plasma Available for Preorder
Powered by an AMD Ryzen CPU, the latest KDE Slimbook laptop is powerful enough for local AI tasks.
-
Rhino Linux Announces Latest "Quick Update"
If you prefer your Linux distribution to be of the rolling type, Rhino Linux delivers a beautiful and reliable experience.