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
-
Gnome 48 Debuts New Audio Player
To date, the audio player found within the Gnome desktop has been meh at best, but with the upcoming release that all changes.
-
Plasma 6.3 Ready for Public Beta Testing
Plasma 6.3 will ship with KDE Gear 24.12.1 and KDE Frameworks 6.10, along with some new and exciting features.
-
Budgie 10.10 Scheduled for Q1 2025 with a Surprising Desktop Update
If Budgie is your desktop environment of choice, 2025 is going to be a great year for you.
-
Firefox 134 Offers Improvements for Linux Version
Fans of Linux and Firefox rejoice, as there's a new version available that includes some handy updates.
-
Serpent OS Arrives with a New Alpha Release
After months of silence, Ikey Doherty has released a new alpha for his Serpent OS.
-
HashiCorp Cofounder Unveils Ghostty, a Linux Terminal App
Ghostty is a new Linux terminal app that's fast, feature-rich, and offers a platform-native GUI while remaining cross-platform.
-
Fedora Asahi Remix 41 Available for Apple Silicon
If you have an Apple Silicon Mac and you're hoping to install Fedora, you're in luck because the latest release supports the M1 and M2 chips.
-
Systemd Fixes Bug While Facing New Challenger in GNU Shepherd
The systemd developers have fixed a really nasty bug amid the release of the new GNU Shepherd init system.
-
AlmaLinux 10.0 Beta Released
The AlmaLinux OS Foundation has announced the availability of AlmaLinux 10.0 Beta ("Purple Lion") for all supported devices with significant changes.
-
Gnome 47.2 Now Available
Gnome 47.2 is now available for general use but don't expect much in the way of newness, as this is all about improvements and bug fixes.