systemd is an initialization system and service manager that has emerged as the new standard for Linux distributions. Though the learning curve for
systemd can be steep due to its intricate adoption, mastering it can greatly streamline server administration tasks. Familiarizing yourself with the tools and daemons comprised within
systemd will enable you to unlock its potential and flexibility, or at the very least, perform tasks more seamlessly.
In this guide, we will look at the
systemctl command, a vital management instrument for governing the initialization system. We will explore techniques for managing services, checking statuses, modifying system states, and interacting with configuration files.
It's important to note that not all Linux distributions have implemented
systemd as their default initialization system. If you encounter the error bash: systemctl is not installed when following this guide, it is probable that your machine employs a different initialization system.
The main function of an initialization system is to launch components that need to be initialized following the booting of the Linux kernel (commonly referred to as "userland" components). Additionally, the initialization system is responsible for managing services and daemons while the system is operating. With this context, we will commence with several basic service management procedures.
systemd, the primary subjects of most actions are "units," which signify resources that
systemd can oversee. Units are categorized by the kind of resource they embody and are defined using files called unit files. The category of each unit can be deduced from the suffix appended to the file.
For service management operations, the target units will be service units, which possess unit files with a .service suffix. Nevertheless, in the majority of service management commands, you can exclude the .service suffix, as
systemd can easily discern that you likely intend to interact with a service utilizing service management commands.
Starting and Stopping Services
To start a
systemd service with the instructions in the service unit file, use the
start command. If operating as a non-root user,
sudo will be necessary, as this action impacts the state of the operating system:
sudo systemctl start application.service
As previously noted,
systemd will search for *.service files for service management commands, permitting the command to be input like this:
sudo systemctl start application
While this format is suitable for general administration, we will utilize the .service suffix for the subsequent commands to explicitly denote the target being worked with.
To halt an active service, apply the
sudo systemctl stop application.service
Restarting and Reloading
To restart a functioning service, employ the
sudo systemctl restart application.service
If the application concerned can reload configuration files (without restarting), initiate this process using the
sudo systemctl reload application.service
If uncertain whether the service can reload its configuration, issue the
reload-or-restart command. This will lead to the configuration being reloaded if possible. If not, the service will restart to apply the updated configuration:
sudo systemctl reload-or-restart application.service
Enabling and Disabling Services
The aforementioned commands are helpful for initiating or terminating services during the present session. To instruct
systemd to automatically start services at boot, they must be enabled.
To start a service at boot, utilize the
sudo systemctl enable application.service
This action generates a symbolic link from a system copy of the service file (typically in /lib/systemd/system or /etc/systemd/system) to the location on disk where
systemd searches for files to autorun (usually /etc/systemd/system/some_target.target.wants). We will look at what a target is later in this manual).
To disable automatic start of a service, input:
sudo systemctl disable application.service
This will eliminate the symbolic link that signified the service should initiate automatically.
Keep in mind that enabling the service will not activate it in the current session. To both start the service and enable it at boot, you must provide both commands,
Checking the status of services
To check the status of a service on your system, utilize the
systemctl status application.service
This provides information on the service's status, control group hierarchy, and initial log entries.
For instance, when verifying the status of a Nginx server, the following output might be displayed:
● nginx.service - A high performance web server and a reverse proxy server
Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled)
Active: active (running) since Tue 2015-01-27 19:41:23 EST; 22h ago
Main PID: 495 (nginx)
├─495 nginx: master process /usr/bin/nginx -g pid /run/nginx.pid; error_log stderr;
└─496 nginx: worker process
Jan 27 19:41:23 desktop systemd: Starting A high performance web server and a reverse proxy server...
Jan 27 19:41:23 desktop systemd: Started A high performance web server and a reverse proxy server.
This offers a comprehensive overview of the application's current status and alerts you to any issues or necessary actions.
There are also methods to check for specific statuses. For instance, to determine whether a module is presently active, use the
systemctl is-active application.service
This returns the module's current status, typically active or inactive. If active, the exit code will be "0," making the result easier to parse in shell scripts.
To see if a module is enabled, apply the
systemctl is-enabled application.service
This displays whether the service is enabled or disabled and sets the output code to "0" or "1" based on the command's inquiry.
The third check involves determining if the module is in a failed state, indicating an issue with starting the unit:
systemctl is-failed application.service
This returns active if functioning correctly or failed in case of an error. If the module was deliberately stopped, it may return unknown or inactive. An output status of "0" signifies a failure, while an output status of "1" represents a different status.
System State Overview
While the previous commands are useful for managing single services, they offer limited insight into the overall system state. Several
systemctl commands can help provide this information.
Listing Current Units
To display a list of all active units recognized by
systemd, use the
This reveals a list of all units currently active within the system. The output may appear as follows:
UNIT LOAD ACTIVE SUB DESCRIPTION
atd.service loaded active running ATD daemon
avahi-daemon.service loaded active running Avahi mDNS/DNS-SD Stack
dbus.service loaded active running D-Bus System Message Bus
dcron.service loaded active running Periodic Command Scheduler
dkms.service loaded active exited Dynamic Kernel Modules System
[email protected] loaded active running Getty on tty1
. . .
The output consists of the following columns:
LOAD: Indicates if the unit’s configuration has been parsed by
systemd. The configuration of loaded units is stored in memory.
- ACTIVE: A summary state indicating whether the unit is active. This typically reveals whether the unit has started successfully.
- SUB: A more detailed state providing additional information about the unit. This often varies depending on the unit type, state, and how the unit operates.
- DESCRIPTION: A brief description of what the unit is/does.
By default, the
list-units command only shows active units. Thus, all entries will display loaded in the LOAD column and active in the ACTIVE column. Executing
systemctl without additional commands produces the same display:
To obtain different information, add extra flags. For example, use the
--all flag to see all units
systemd has loaded (or attempted to load), irrespective of their current activity:
systemctl list-units --all
This displays any unit that
systemd loaded or tried to load, regardless of its system state. Some units become inactive after running, while others may not be found on disk after
systemd attempts to load them.
You can use other flags to filter the results. For example, the
--state= flag specifies the LOAD, ACTIVE, or SUB states to display. Keep the
--all flag so that
systemctl shows non-active units:
systemctl list-units --all --state=inactive
Another common filter is the
--type= filter. To display only units of a particular type, use:
systemctl list-units --type=service
Listing All Unit Files
list-units command only displays units that
systemd has tried to parse and load into memory. Since
systemd only reads the units it deems necessary, this list may not include all available units. To view every unit file within
systemd paths, including those not attempted to load, use the
Units represent resources known to
systemd. As not all unit definitions are necessarily read in this view, it only presents information about the files themselves. The output features two columns: the unit file and its state.
UNIT FILE STATE
. . .
States are typically enabled, disabled, static, or masked. In this context, static means the unit file lacks an install section required to enable a unit. As such, these units cannot be enabled. This usually implies that the unit carries out a one-time action or serves as a dependency for another unit and should not be run independently.
Next, we'll discuss the meaning of masked.
We've been working with services and displaying unit and unit file information that
systemd recognizes. To learn more specific information about units, we can use additional commands.
Displaying a Unit File
To display the unit file that
systemd has loaded into its system, utilize the
cat command (introduced in
systemd version 209). For example, to display the unit file for the atd scheduling daemon, enter:
systemctl cat atd.service
The output reveals the unit file as recognized by the currently running
systemd process. This is important if you've recently modified unit files or if you're overriding specific options in a unit file fragment (we'll discuss this later).
To view a unit's dependency tree, use
the list-dependencies command:
systemctl list-dependencies sshd.service
This shows a hierarchy outlining the dependencies that must be addressed to start the given unit. Dependencies include units either required or wanted by the units above them.
. . .
The recursive dependencies are only displayed for .target units, which indicate system states. To recursively list all dependencies, include the
To display reverse dependencies (units depending on the specified unit), include the
--reverse flag. The
--after flags are also helpful, showing units that depend on the specified unit starting before or after themselves, respectively.
Checking Unit Properties
To view a unit's low-level properties, use the
show command. This displays a list of properties set for the specified unit in a key=value format:
systemctl show sshd.service
After=syslog.target network.target auditd.service systemd-journald.socket basic.target system.slice
Description=OpenSSH server daemon
. . .
To display a single property, use the
-p flag with the property name. For example, to see conflicts related to the sshd.service unit, enter:
systemctl show sshd.service -p Conflicts
Masking and Unmasking Units
We've seen how to stop or disable a service, but
systemd also enables marking a unit as entirely unstartable, either automatically or manually, by linking it to /dev/null. This is called masking the unit and can be accomplished with the
sudo systemctl mask nginx.service
This prevents the Nginx service from starting, either automatically or manually, as long as it remains masked.
When checking the list-unit-files, the service now appears as masked:
. . .
. . .
Attempting to start the service produces the following message:
sudo systemctl start nginx.service
Failed to start nginx.service: Unit nginx.service is masked.
To unmask a unit and make it available for use again, use the
sudo systemctl unmask nginx.service
This returns the unit to its previous state, allowing it to be started or enabled.
Editing Unit Files
The specific format for unit files falls outside the scope of this guide, but
systemctl includes built-in tools for editing and modifying unit files when adjustments are required. This feature was introduced in
systemd version 218.
By default, the
edit command opens a snippet for the specified unit:
sudo systemctl edit nginx.service
This blank file allows you to override or add directives to the unit definition. A directory is created in the /etc/systemd/system directory, with the unit's name appended with .d. For example, a directory called nginx.service.d is created for the nginx.service.
Inside this directory, an override.conf snippet is created. When the unit is loaded,
systemd merges the override snippet with the full unit file in memory. The snippet's directives take precedence over those in the original unit file.
If you prefer to edit the entire unit file instead of creating a snippet, use the
sudo systemctl edit --full nginx.service
This command opens the current unit file in the editor, where you can make modifications. Upon exiting the editor, the modified file is saved to /etc/systemd/system, overriding the system's unit definition (typically found in /lib/systemd/system).
To remove any changes you've made, delete the unit's .d configuration directory or the modified service file from /etc/systemd/system. For example, to remove a snippet, enter:
sudo rm -r /etc/systemd/system/nginx.service.d
To remove a fully modified unit file, enter:
sudo rm /etc/systemd/system/nginx.service
After deleting the file or directory, reload the
systemd process so it no longer references these files and reverts to using the system copies. This can be done by entering:
sudo systemctl daemon-reload
Adjusting the System State (Runlevel) with Targets
Targets represent unique unit files that describe a system state or synchronization point. Like other units, the files that define targets can be identified by their suffix, which in this case is .target. Although they don't do much on their own, targets are utilized to group other units together.
Targets help bring the system to certain states, similar to runlevels in other init systems. They serve as a reference for when specific functions are accessible, allowing the desired state to be specified instead of the individual units needed to achieve that state.
For example, a swap.target indicates that swap is ready to be used. Units involved in this process can synchronize with this target by specifying in their configuration that they are WantedBy= or RequiredBy= the swap.target. Units that require swap to be available can specify this condition using the Wants=, Requires=, and After= specifications to indicate the nature of their relationship.
Getting and Setting the Default Target
Systemd has a default target that it utilizes when booting the system. Satisfying the dependencies of that single target brings the system to the desired state. To identify your system's default target, enter:
To set a different default target, use the
set-default command. For example, if you have a graphical desktop installed and want the system to boot into it by default, change your default target accordingly:
sudo systemctl set-default graphical.target
Listing Available Targets
To view a list of available targets on your system, enter:
systemctl list-unit-files --type=target
Multiple targets can be active simultaneously. An active target signifies that
systemd has attempted to start all units linked to the target and has not tried to stop them again. To view all active targets, enter:
systemctl list-units --type=target
Starting all units associated with a target and stopping all units not part of the dependency tree is possible. The command to achieve this is called
isolate, which is akin to changing the runlevel in other initialization systems.
For example, if operating in a graphical environment with an active graphical.target, you can shut down the graphical system and transition the system into a multi-user command line state by isolating the multi-user.target. Since graphical.target depends on multi-user.target but not vice versa, all graphical units will be stopped.
Before isolating a target, you might want to review its dependencies to ensure you're not stopping essential services:
systemctl list-dependencies multi-user.target
Once you're satisfied with the units that will remain active, isolate the target by entering:
sudo systemctl isolate multi-user.target
Using Shortcuts for Important Events
Targets are designed for significant events like powering off or rebooting. However,
systemctl also offers shortcuts that provide extra functionality.
For example, to enter rescue (single-user) mode, use the
rescue command instead of
sudo systemctl rescue
This adds the benefit of notifying all logged-in users about the event.
To halt the system, use the
sudo systemctl halt
For a complete shutdown, employ the
sudo systemctl poweroff
To restart, use the
sudo systemctl reboot
These commands inform logged-in users of the event, which running or isolating the target alone won't do. Note that most machines link the shorter, more conventional commands for these operations to work correctly with
For instance, to reboot the system, you can typically type:
By now, you should be acquainted with the fundamental features and capabilities of the
systemctl command, allowing you to interact with and manage a
systemd instance. The
systemctl utility serves as the primary interaction point for service and system state management.
systemctl primarily works with the main
systemd process, other components in the
systemd ecosystem are controlled by different utilities. Other functionalities, like log management and user sessions, are managed by separate daemons and management utilities (
loginctl, respectively). Taking the time to familiarize yourself with these other tools and daemons will make management tasks easier.