By Juraj Holub
Last Validated on May 3 2021 · Originally Published on May 3, 2021 · Viewed 3.8k times

Introduction

This tutorial shows you how to control the daemon systemd with utility systemctl.

Every operating system uses various background processes that maintain the system. In Linux, they are called daemons. Daemons are started and maintained by the initialisation daemon that starts immediately after system boot. The most popular distribution uses daemon systemd (Debian 8, Ubuntu 15.04, Fedora 15, CentOS 7, and their higher versions).

In this tutorials you will learn the following:

  • How to find systemd unit files, view them, and edit them.
  • How to check status, start, stop, enable, disable, reload, and restart systemd service with systemctl utility.

Prerequisites

You will need:

  • Ubuntu 20.04 distribution including the non-root user with sudo access.
  • Basic knowledge of rsyslog service. All examples will be demonstrated on the rsyslog service.

Step 1 — Viewing Systemd Unit Files

Systemd's most important abstraction is the unit. The unit represents any resource maintained by operating systems such as daemons, sockets, devices, and many others. We will target only a service unit.

Each specific unit of systemd has its own configuration, and typically, it has multiple configurations with various priority and scope. They are saved in various configuration files that are called unit files. Generally, unit files are saved in these three directories (listed in ascending priority):

  1. /lib/systemd/system contains general unit files with the lowest priority. They are part of the standard system implementation and you shouldn't modify them.
  2. /run/systemd/system contains the runtime unit configuration. These files change unit behaviour at runtime. These files are created dynamically, and they exist only for the actual boot session.
  3. /etc/systemd/system contains unit files with the highest priority. If you need to change the unit configuration, you typically edit unit files in this directory.

Unit-Specific Configuration

In case that you need to edit only a specific option in the unit file, you can create a specific subdirectory where you specify the new option. Usually, the new directory is named as unit service with .d suffix (for example, subdirectory example.d belongs to the example unit). This subdirectory holds various files with the .conf suffix that edits and extends unit configuration.

You can execute ls to list all units in /etc that use unit-specific configuration:

ls -d /etc/*.d

The option -d lists only directories. The regular expression /etc/*.d specifies to list all directories in /etc that end with the .d suffix.

Output
/etc/apparmor.d         /etc/ld.so.conf.d    /etc/rc1.d      /etc/sensors.d
/etc/bash_completion.d  /etc/libibverbs.d    /etc/rc2.d      /etc/sudoers.d
/etc/binfmt.d           /etc/libpaper.d      /etc/rc3.d      /etc/sysctl.d
/etc/cron.d             /etc/logrotate.d     /etc/rc4.d      /etc/tmpfiles.d
/etc/depmod.d           /etc/modprobe.d      /etc/rc5.d      /etc/update-motd.d
/etc/environment.d      /etc/modules-load.d  /etc/rc6.d      /etc/usb_modeswitch.d
/etc/grub.d             /etc/pam.d           /etc/rcS.d
/etc/init.d             /etc/profile.d       /etc/rsyslog.d
/etc/insserv.conf.d     /etc/rc0.d           /etc/sane.d

The output shows all these unit configuration directories. You can spot the logrotate service for example. This is the place where you can edit, or create a new logrotate setup (for more information, see How to Manage Logs with Logrotate on Ubuntu 20.04 ).


Structure Of Unit File

The structure of the unit file is precisely defined. Each unit file is divided into sections, and sections consist of directives.

Let's view content of the unit file for rsyslog service in /etc/systemd/system by executing cat:

cat /etc/systemd/system/syslog.service

You’ll see the program’s output appear on the screen:

Output
[Unit]
Description=System Logging Service
Requires=syslog.socket
Documentation=man:rsyslogd(8)
Documentation=https://www.rsyslog.com/doc/

[Service]
Type=notify
ExecStart=/usr/sbin/rsyslogd -n -iNONE
StandardOutput=null
Restart=on-failure

# Increase the default a bit in order to allow many simultaneous
# files to be monitored, we might need a lot of fds.
LimitNOFILE=16384

[Install]
WantedBy=multi-user.target
Alias=syslog.service

The output shows definitions of sections and their directives for service rsyslog. Each directive starts at a new line with a keyword followed by a value (for example Description=System Logging Service). In our case, there are three sections:

  • [Unit]: Defines metadata of unit and relations to the other units. You can see that it is a system logging service, it requires syslog.socket unit, and that you can view the man page of rsyslogd for more details.
  • [Service]: This section is used only for the configuration of the service unit. The most common directive in this section is the Type that defines start-up settings for service. In our case (Type=notify), the system starts the unit immediately after service binary execution, but it is expected that the service sends a special notification message. The ExecStart defines a command to execute when service starts.
  • [Install]:  This section defines the behaviour of the unit after it is enabled. Directive WantedBy specifies which units must be enabled too because this unit requires them. Directive Alias defines name alternative for the unit (in our case the rsyslog, and syslog are the same systemd units).

These three sections are most often used once. However, there can also be other sections, and each section can define much more directives than in our example. For more information about sections and their directives see the following article.


Step 2 — Checking The Service Status With Systemctl

The systemctl is a command-line utility that controls the systemd and its units. This tool allows to check the status of the unit, lists all system units, disables, or enables them, starts new, and similar control actions.

Let's view a list of all available units on your system. You don't need the root access for viewing unit status. Run systemctl with parameter list-units:

systemctl list-units --type=service --no-pager

The option --type=service shows only units that are a type of service, and the option --no-pager prevents pipe output to the pager. You’ll see the program’s output appear on the screen:

Output
UNIT                        LOAD   ACTIVE SUB     DESCRIPTION                 
  accounts-daemon.service     loaded active running Accounts Service            
  acpid.service               loaded active running ACPI event daemon           
  alsa-restore.service        loaded active exited  Save/Restore Sound Card Sta…
  apparmor.service            loaded active exited  Load AppArmor profiles      
  apport.service              loaded active exited  LSB: automatic crash report…
  avahi-daemon.service        loaded active running Avahi mDNS/DNS-SD Stack     
  bluetooth.service           loaded active running Bluetooth service           
● certbot.service             loaded failed failed  Certbot                     
  clean-mount-point@media-al… loaded active exited  Clean the /media/alice/Exte…
  rsyslog.service             loaded active running System Logging Service  
  colord.service              loaded active running Manage, Install and Generat…
  console-setup.service       loaded active exited  Set console font and keymap 
  cron.service                loaded active running Regular background program …
  cups-browsed.service        loaded active running Make remote CUPS printers a…
  cups.service                loaded active running CUPS Scheduler              
  dbus.service                loaded active running D-Bus System Message Bus    
...

The systemctl show a very long and detailed list of all units and their status. For example, you can recognise the rsyslog service.

You can also view the detailed status of a specific unit. Let's view the status of rsyslog service by executing systemctl with parameter status:

systemctl status rsyslog.service --no-pager

You’ll see the program’s output appear on the screen:

Output
● rsyslog.service - System Logging Service
     Loaded: loaded (/lib/systemd/system/rsyslog.service; enabled; vendor preset: enabled)
     Active: active (running) since Thu 2021-03-25 19:20:26 CET; 2 weeks 5 days ago
TriggeredBy: ● syslog.socket
       Docs: man:rsyslogd(8)
             <https://www.rsyslog.com/doc/>
   Main PID: 8099 (rsyslogd)
      Tasks: 4 (limit: 19026)
     Memory: 3.6M
     CGroup: /system.slice/rsyslog.service
             └─8099 /usr/sbin/rsyslogd -n -iNONE

mar 25 19:20:26 alice systemd[1]: rsyslog.service: Succeeded.
mar 25 19:20:26 alice systemd[1]: Stopped System Logging Service.
mar 25 19:20:26 alice systemd[1]: Starting System Logging Service...
mar 25 19:20:26 alice rsyslogd[8099]: imuxsock: Acquired UNIX socket '/…1.0]
mar 25 19:20:26 alice rsyslogd[8099]: rsyslogd's groupid changed to 110
mar 25 19:20:26 alice rsyslogd[8099]: rsyslogd's userid changed to 104
mar 25 19:20:26 alice rsyslogd[8099]: [origin software="rsyslogd" swVer…tart
mar 25 19:20:26 alice systemd[1]: Started System Logging Service.

The output shows detailed info about this service. You can see that it is enabled, and it is active for almost three weeks. At the end of the output is a few most recent log data from the journal.

Usually, you are not interested in such a detailed output, and you only want to know if the service is active, inactive, enabled, or disabled. In such a case, you can use systemctl with the parameter is-active, or is-enabled.

Let's run systemctl with parameter is-active for rsyslog:

systemctl is-active rsyslog.service

The systemctl shows simple boolean status:

Output
active

The output shows that rsyslog service is active.

Next, let's run systemctl with parameter is-enabled for rsyslog:

systemctl is-enabled rsyslog.service

Once again, the systemctl shows simple boolean status:

Output
enabled

The output shows that rsyslog service is enabled.


Step 3 — Stopping And Starting Service With Systemctl

Now, you will edit service status with systemctl. In the following examples, we will use systemctl with sudo because the modification of the systemd unit requires root access. The systemctl with parameter stop can stop systemd unit service. Alternatively, systemctl with parameter start does the opposite operation. Both operations are executed at runtime and they are not persistent. As a result, if you start (or stop) some service, it won't start (or stop) after reboot.

Your Ubuntu distributions include already enabled rsyslog service. Let's stop it by execution systemctl stop command:

sudo systemctl stop rsyslog.service

You’ll see the program’s output appear on the screen:

Output
Warning: Stopping rsyslog.service, but it can still be activated by:
  syslog.socket

The output shows that the rsyslog.service is in relation to syslog.socket unit. If you stop only rsyslog, it will start immediately on demand of syslog.

You can check that both units are still active:

systemctl is-active rsyslog.service syslog.socket

The command shows result for both units in the equivalent order to given arguments:

Output
active
active

Let's try to stop both units:

sudo systemctl stop rsyslog.service syslog.socket

If systemctl doesn't show any output then the operation finished successfully. You can check that both services are now inactive with systemctl is-active.

Both units are important for system, so let's start them again with start parameter:

sudo systemctl start rsyslog.service syslog.socket

Similarly to the stop command, if systemctl doesn't show any output then the operation finished successfully. Once again, you can check it with systemctl is-active.


Step 4 — Disabling And Enabling Service With Systemctl

The systemctl with the parameter stop or start is useful when you want to stop or start the unit immediately during the actual session. However, if you want to set up a persistent configuration that will start or stop the unit immediately after each reboot, you can use systemctl with parameter enable or disable.

You can disable rsyslog service with systemctl:

sudo systemctl disable rsyslog.service

You’ll see the program’s output appear on the screen:

Output
Synchronizing state of rsyslog.service with SysV service script with /lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install disable rsyslog
Removed /etc/systemd/system/syslog.service.
Removed /etc/systemd/system/multi-user.target.wants/rsyslog.service.

The output shows that systemctl removes unit files related to rsyslog. Next boot session, the systemd won't find configuration for this service. As a result, it won't start.

Let's check new rsyslog status:

systemctl status rsyslog.service

You’ll see the program’s output appear on the screen:

Output
● rsyslog.service - System Logging Service
     Loaded: loaded (/lib/systemd/system/rsyslog.service; disabled; vendor preset: enabled)
     Active: active (running) since Thu 2021-04-15 08:45:46 CEST; 38min ago
       Docs: man:rsyslogd(8)
             <https://www.rsyslog.com/doc/>
   Main PID: 23838 (rsyslogd)
      Tasks: 4 (limit: 19026)
     Memory: 1.2M
     CGroup: /system.slice/rsyslog.service
             └─23838 /usr/sbin/rsyslogd -n -iNONE

The output shows that the rsyslog is active but it is also disabled. This means that in the next boot it won't start again. But it still works till the end of the actual session.

The rsyslog is an important system service, so you should enable it back. You can enable it with systemctl:

sudo systemctl enable rsyslog.service

You’ll see the program’s output appear on the screen:

Output
Synchronizing state of rsyslog.service with SysV service script with /lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install enable rsyslog
Created symlink /etc/systemd/system/syslog.service → /lib/systemd/system/rsyslog.service.
Created symlink /etc/systemd/system/multi-user.target.wants/rsyslog.service → /lib/systemd/system/rsyslog.service.

The systemctl creates unit files for the rsyslog unit. In the next boot, the system will find this configuration file, and it will start this service. Now, you can check the status of this service, and it will be enabled.


Step 5 — Reloading And Restarting Sevice With Systemctl

Another typical systemctl use case is that you change a service-specific configuration file and you want to immediately reflect changes. If your application can reload configuration without restarting then you can use systemctl reload, otherwise, you can restart the entire service with systemctl restart.

You can try to reload rsyslog service with systemctl:

sudo systemctl reload rsyslog.service

You’ll see the program’s output appear on the screen:

Output
Failed to reload rsyslog.service: Job type reload is not applicable for unit rsyslog.service.

The output shows you that you cannot reload it. In such a type of service, you must to restart it.

Let's try to restart rsyslog service and then immediately check status of this service:

sudo systemctl restart rsyslog.service && systemctl status rsyslog.service

If the service restart finished successfully than you’ll see the status output appear on the screen:

Output
● rsyslog.service - System Logging Service
     Loaded: loaded (/lib/systemd/system/rsyslog.service; enabled; vendor preset: enabled)
     Active: active (running) since Thu 2021-04-15 09:56:45 CEST; 18ms ago
TriggeredBy: ● syslog.socket
       Docs: man:rsyslogd(8)
             <https://www.rsyslog.com/doc/>
   Main PID: 28793 (rsyslogd)
      Tasks: 4 (limit: 19026)
     Memory: 1.2M
     CGroup: /system.slice/rsyslog.service
             └─28793 /usr/sbin/rsyslogd -n -iNONE

The status shows that the rsyslog service is active for 18ms, or in other words, it is active just after restart.


Conclusion

In this tutorial, you viewed systemd unit files. You learned how to control systemd with systemctl, and you practised following systemctl commands:

  • Check status of service.
  • Stop and start service.
  • Disable and enable service.
  • Reload and restart service.