If you've meddled with Linux even a little, you may have heard of systemctl. It's a tool used to control and inspect systemd, a system service manager, and init system. systemctl is most commonly used to stop, start, and restart services, but it can also be utilized to enable a service at boot or check the status of services.

What is systemctl?

Today, we're going to be showing you how to perform all of the above, while explaining some core concepts surrounding the tools so you can gain a better understanding. First, some terminology:

  • systemd initializes user space components when the Linux kernel has finished its boot process. It also maintains them through the course of the system's operation.
  • The components systemd manages are known as units, which each have a unit file.
  • Units can control the configuration of hardware, services, sockets, and more.
  • Targets let systemd easily tell which unit files are needed to produce a system state. They're represented by target units.

Our test system during all this will be a BitLaunch VPS running Ubuntu 20.02, but the concepts and commands shown should work on most Linux distros. Let's first look at how to control services in Linux:

How to Stop, Start, Check and Restart a Service with systemctl

Being able to stop, start, or restart a service with systemctl can be very useful if a piece of software isn't responding or you need to start a certain task. You can start a systemd service with the following systemctl command:

sudo systemctl start yourservice

And stop a service via:

sudo systemctl stop yourservice

If you need to perform a systemctl restart a or reload a service's configuration file you can enter:

sudo systemctl reload-or-restart yourservice

At times, though, it can be useful to check the status of a service before taking action. You can check your currently running systemd service units with:

systemctl list-units --type=service

This will return an output like this:

 UNIT                                 LOAD   ACTIVE SUB     DESCRIPTION
  accounts-daemon.service              loaded active running Accounts Service
  apparmor.service                     loaded active exited  Load AppArmor profiles
  apport.service                       loaded active exited  LSB: automatic crash report generation
device nodes for the current kernel
  lvm2-monitor.service                 loaded active exited  Monitoring of LVM2 mirrors, snapshots etc. using dmeventd or progress polling
  monitorix.service                    loaded active running Monitorix
  netfilter-persistent.service         loaded active exited  netfilter persistent configuration
  networkd-dispatcher.service          loaded active running Dispatcher daemon for systemd-networkd
  plexmediaserver.service              loaded active running Plex Media Server

We can then check on one of those services, for example Plex Media Server, with the systemctl status command:

systemctl status plexmediaserver

It will return:

 plexmediaserver.service - Plex Media Server
     Loaded: loaded (/lib/systemd/system/plexmediaserver.service; enabled; vendor preset: enabled)
     Active: active (running) since Sat 2020-08-08 19:58:00 UTC; 1 weeks 4 days ago
   Main PID: 3990 (Plex Media Serv)
      Tasks: 43 (limit: 614)
     Memory: 96.7M
     CGroup: /system.slice/plexmediaserver.service
             ├─ 506 Plex Plug-in [com.plexapp.system] /usr/lib/plexmediaserver/Resources/Plug-ins-b23ab3896/Framework.bundle/Contents/Resources/Versions/2/Python/bootstrap.py --server-versi>
             ├─3990 /usr/lib/plexmediaserver/Plex Media Server
             └─4088 /usr/lib/plexmediaserver/Plex Tuner Service /usr/lib/plexmediaserver/Resources/Tuner/Private /usr/lib/plexmediaserver/Resources/Tuner/Shared 1.19.5.3112-b23ab3896 32600 >

This will show you how much memory a task is using, as well as the number of tasks under its umbrella and various other data.

How to Run a Service at Boot with systemctl

Running services at boot is another very common use of systemctl, especially in servers. You can tell a service to run at startup by typing:

sudo systemctl enable yourservice

If it's necessary to disable it again, enter the systemctl disable command:

sudo systemctl disable yourservice

If the service isn't found, you may need to point to its direct file path with:

sudo systemctl enable /path/to/yourservice.service

However, this won't work if the file isn't on the root file system.

Unit Files

As mentioned previously, each unit has a systemd unit file, and it's this file that encodes information about a service, socket, partition, or mount point. Like any other config file, a unit file can be edited with your favorite text editor to modify how a unit behaves.

Editing a unit file  with sudo systemctl edit ssh requires an understanding of its contents, something that we'll leave to the official documentation. For now, know that you can list your unit files with:

systemctl list-dependencies cron

The output will display all of their dependencies, like so:

cron.service
● └─multi-user.target
●   └─graphical.target

We now know that for cron.service to run, multi-user.target must also be running, which in turn requires graphical.target.

Targets

As mentioned earlier, target units aid in the unit file organization, grouping together units via a chain of dependencies. Symlinks are crafted in .target.wants when a service is enabled, making it a dependency of that target.

You can see that in our earlier dependency list it ended at graphical.target. You can see the default target by running the command:

systemctl get-default

You can also change the target like this:

sudo systemctl set-default graphical.target

Running systemctl list-dependencies cron again will now return a different result.

To list the targets that are available for you to set as the default, type:

systemctl list-unit-files --type=target

Alternatively, you can use systemctl list-units --type=target . You can also change the active target via the isolate command, checking its dependencies to make sure nothing important is stopped first with:

systemctl list-dependencies your.target

And then running:

sudo systemctl isolate your.target.

Rescue and Emergency Modes

systemctl can also be used to repair your system if it runs into a problem that makes it impossible to boot normally. You can then use this minimal UI to make changes. The first thing to try is the systemctl rescue mode:

sudo systemctl rescue

You can also use the systemctl emergency mode, which is even more minimal and can be utilized if you can't start rescue mode:

sudo systemctl emergency

Shutdown, reboot, or halt via systemctl

You can additionally use systemctl to shutdown, halt, or reboot a system if other methods are proving difficult:

sudo systemctl shutdown

sudo systemctl halt

sudo systemctl reboot

You can find more advanced knowledge about systemctl and systemd units on their respective Ubuntu man pages.