Systemd on Linux – Manage Services, Run Levels and Logs
Systemd is not only a service manager but also a system manager for Linux. It’s designed to be backward compatible with SysV init scripts and used by many popular Linux distributions like Debian 8+, Ubuntu 15.04+, Fedora, Redhat 7+ /CentOS 7+, Arch Linux, OpenSUSE. So it will be very helpful to know how to use systemd.
This tutorial shows you some basic commands that will be useful to manage services, run levels, and logs. First, you might want to know the systemd version on your Linux distribution, run
systemd --version
or
systemctl --version
Managing Services
Systemd can help you start, stop, restart services and also allows you to auto-start services at boot time.
To list active systemd services, run
systemctl list-units --type service
Check the status of a specific service, for example, SSH daemon.
systemctl status ssh
To start a service, use the start
subcommand:
sudo systemctl start ssh
Check if it’s active (running)
systemctl is-active ssh
Enable a service to autostart at boot time
sudo systemctl enable ssh
Check if it’s enabled
systemctl is-enabled ssh
Prevent a service from starting up at boot time
sudo systemctl disable ssh
Stop a service
sudo systemctl stop ssh
You disabled a systemd service, but it somehow started again? To prevent a service from starting manually, use the mask
subcommand.
sudo systemctl mask ssh
Masked services can’t be started with systemctl start
command until it’s unmasked.
sudo systemctl unmask ssh
Sometimes, you may find an unknown process is running with the htop
command. You want to stop it, but don’t know which systemd service it belongs to. In this case, you can run the following command
systemctl status
This command will give you a list of active systemd service units and the commands used to start them.
Managing Run Levels
The concept of run levels is replaced by targets in systemd. The multi-user.target
is equivalent to run level 3 and the graphical.target
is equivalent to run level 5. You can still use the runlevel command to show the current run level.
runlevel
Use the following command to check the status of the default target, which by default is usually the graphical target (run level 5).
systemctl status default.target
You use systemctl isolate
command to change target. For example, change to the multi-user.target (run level 3):
sudo systemctl isolate multi-user.target
And to change back to graphical target (run level 5):
sudo systemctl isolate graphical.target
To set multi-user.target
as the default target, use the following command:
sudo systemctl set-default multi-user.target
This command creates a symbolic link.
If you reboot now, you will be taken to multi-user target.
To list active targets, run
systemctl list-units --type target
Managing Logs
The systemd software suite includes a journalctl
utility which can be used to manage logs on Linux. Linux traditionally saves logs under /var/log/
directory. On a Linux distribution with systemd, you may not be able to find logs such as postfix mail logs (/var/log/mail.log
) in that directory.
You can view recent logs with the following command. You can press F
key to jump to the next page and press B
key to going back to the previous page. Press Q
to quit.
sudo journalctl
Use grep
to search for logs related to your search term
sudo journalctl | grep <search term>
View logs since the current boot
sudo journalctl -b
View logs since the previous boot
sudo journalctl -b -1
Here’s a little trick to show logs being generated in real time.
sudo journalctl -f
Show logs of a unit, for instance, the ssh
service unit.
sudo journalctl -u ssh
To view Postfix logs, run
sudo journalctl -u postfix
Some packages may still be configured to save logs to plain files such as the Postfix log files on Ubuntu (/var/log/mail.log
), so you can use a command-line text editor to peruse the logs. Sometimes a systemd service might stop producing log messages, you can try to restart rsyslog
to solve this problem.
sudo systemctl restart rsyslog
Conflicting Services
When two services shouldn’t run at the same time, you can use the Conflicts
parameter. For example, I always use a VPN on my Ubuntu desktop computer. It’s a self-hosted VPN running on a VPS. Then I sometimes use Transmission to download torrents. When I start Transmission, I must close the VPN connection, because Vultr will shut down your account if you use their servers to download torrents (I mean downloading copyright-infringing materials via BitTorrent).
I can edit the transmission-daemon.service
.
sudo nano /lib/systemd/system/transmission-daemon.service
Add the following line in the [Unit]
section.
Conflicts=openconnect.service
Save and close the file. Then reload systemd for the changes to take effect.
sudo systemctl daemon-reload
openconnect.service
is the service that starts VPN connection on my computer. Now if I start transmission-daemon.service
, openconnect.service
will be automatically shut down, and vice versa.
Wants
If you want service B to start when service A starts, you can use the Wants
parameter to make it happen. In the [Unit]
section of a systemd .service
file, add a line like this:
[Unit] Wants = b.service
You can also use Before =
or After =
to specify the order.
[Unit] Wants = b.service Before = b.service
Sometimes, you may want service B to wait for service A to complete before starting itself. Then you can add the following lines in the [Service]
section of the b.service
file.
[Service] ExecStartPre=/bin/sleep 20
This tells b.service
to wait 20 seconds.
Remember to reload systemd for the changes to take effect.
sudo systemctl daemon-reload
Run /etc/rc.local Scripts
If you are running a Linux distro that uses Systemd, you may find that your commands in /etc/rc.local
file would not run at system boot time. The following tutorial explains how to enable /etc/rc.local
script to run on system startup.
Accounting
Systemd allows you to check how much CPU and memory is used by a service and how many tasks are running by the service. If you are using a recent Linux distro like Ubuntu 20.04, Debian 10, RHEL 8, accounting is enabled by default. On old Linux distros like Ubuntu 18.04, you need to manually enable accounting. Let’s say you want to enable accounting for Nginx on Ubuntu 18.04, then follow the instruction below.
First, we make a directory to store custom systemd configurations for Nginx.
sudo mkdir -p /etc/systemd/system/nginx.service.d/
Create the custom config file under this directory. The filename extension must be .conf
.
sudo nano /etc/systemd/system/nginx.service.d/custom.conf
Then add the following lines in this file.
[Service] CPUAccounting=true MemoryAccounting=true TasksAccounting=true
Save and close the file. Then reload systemd.
sudo systemctl daemon-reload
There’s no need to restart Nginx. Now you can check Nginx status with:
systemctl status nginx
Custom Configuration for Template Systemd Service
You may have seen a template systemd service that contains the @
symbol like the Syncthing service.
/lib/systemd/system/[email protected]
This kind of service allows you to run multiple instances. For example, you can run Syncthing for two users with:
sudo systemctl start syncthing@user1.service sudo systemctl start syncthing@user2.service
If you want to add custom configuration to this kind of service, you need to create a folder for each of these services.
sudo mkdir -p /etc/systemd/system/syncthing@user1.service.d sudo mkdir -p /etc/systemd/system/syncthing@user2.service.d
Then you can create the custom configuration file.
sudo nano /etc/systemd/system/syncthing@user1.service.d/custom.conf sudo nano /etc/systemd/system/syncthing@user2.service.d/custom.conf
After saving your changes. Reload systemd.
sudo systemctl daemon-reload
Systemd Timers
What if you don’t want a systemd service to automatically start at system boot time, but make it run at a specific time? You can create a systemd timer for the systemd service. For example, I created a systemd service (/etc/systemd/system/iris.service)
for the Iris eye protection software.
[Unit]
Description=Iris Eye Protection Software
After=lightdm.service
[Service]
Type=oneshot
Environment=DISPLAY=:0
User=your_username
ExecStart=/bin/bash -c 'DISPLAY=:0 xhost 127.0.0.1 && /opt/iris/Iris.sh'
KillSignal=SIGINT
Restart=on-failure
RestartSec=2
[Install]
WantedBy=multi-user.target
Sure I can make it automatically start at boot time with:
sudo systemctl enable iris.service
What if I want it to start only at night? I need to create a systemd timer.
sudo nano /etc/systemd/system/iris.timer
Add the following lines in this file. This systemd timer will start the iris.service
at 18:00:00 every day.
[Unit] Description=Iris Night Mode Timer Requires=iris.service [Timer] Unit=iris.service OnCalendar=*-*-* 18:00:00 [Install] WantedBy=timers.target
Save and close the file. Then enable this systemd timer.
sudo systemctl enable iris.timer
Check the status of this timer.
sudo systemctl status iris.timer
Sample output:
● iris.timer - Iris Night Mode Timer Loaded: loaded (/etc/systemd/system/iris.timer; enabled; vendor preset: enabled) Active: active (waiting) since Sat 2022-05-07 19:38:22 +08; 24min ago Trigger: Sun 2022-05-08 18:00:00 +08; 22h left Triggers: ● iris.service
Wrapping Up
That’s it! Subscribe to our free newsletter to get the latest Linux tutorials. You can also follow us on Twitter or like our Facebook page.
Absolutely brilliant! Thank you so much for all the amazing articles you put out on Linux!!!
I hate typing out “systemctl” every time I want to call it up. So I just put an “alias sc=systemctl” (and “alias jc=journalctl”) in my .bashrc, and save myself some annoying repetitive typing. Just a suggestion.
Awesome source of information about systemd and the commands to manage it. Thanks very much!
This great info! thanks – I was looking for how to put a command in a service ini file that would tell it to keep a log. I’m having trouble debugging problems with a Linux nginx uwsgi Flask python website and I want to make uwsgi log what it’s doing especially when it fails.