- Senior Writer
- Author
Systemd is the default system and service manager used in most modern Linux distributions. It’s responsible for bringing up the system during boot and managing running services. It takes over process ID 1 (PID 1), which means it’s the very first user-space process started by the Linux kernel and continues running until the system shuts down.
Unlike older init systems like SysV, systemd uses units to define and manage system resources. Each unit is described by a configuration file, known as a unit file, which tells systemd how to manage that resource. Units can represent services, devices, mount points, or even groups of units known as targets, which act like checkpoints during the boot process.
The main tool for interacting with systemd is systemctl, which allows you to start, stop, restart, enable, disable, and check the status of services and other units.
To review system logs related to systemd and its services, you can use journalctl, a command that displays messages from the systemd journal.
In this guide, we will explore how to use systemctl command, a tool for managing the initialization system on Linux. We’ll also discuss how to control services, view their status, adjust system states, and interact with configuration files.
It’s important to mention that while systemd is the default init system in many popular Linux distributions, not every distro uses it. If you see an error like bash: systemctl: command not found, your system likely relies on a different init system, and systemctl isn’t available.
One of the core responsibilities of an init system is to bring up essential components after the Linux kernel finishes loading. These components, often called userland processes, include various services and daemons that keep the system running smoothly. An init system also plays an ongoing role in controlling these services while the system is up and running.
In the case of systemd, the key elements it manages are called units. Units are defined in configuration files called unit files, and each file specifies how a particular resource should be handled. The type of resource is indicated by the file’s extension (suffix).
For managing services specifically, systemd uses service units, which have filenames ending in .service. However, when using systemctl commands, you can usually omit the .service extension—systemd will automatically assume you’re referring to a service.
To manually start a service and trigger the actions defined in its unit file, use the following command:
$ sudo systemctl start application.service
Since systemd can infer that you are working with a service, you could also run:
$ sudo systemctl start application
Both formats work, but for clarity, this guide will consistently include the .service suffix when working with service units.
To stop a service that’s currently running, the command is:
$ sudo systemctl stop application.service
To fully restart a service (which stops and then starts it again), use:
$ sudo systemctl restart application.service
Some services support reloading their configuration files without needing to restart entirely. To trigger a configuration reload, run:
$ sudo systemctl reload application.service
If you aren’t sure whether the service supports reloading, you can use a safer, combined command:
$ sudo systemctl reload-or-restart application.service
This will try to reload the configuration if supported. If not, it will restart the service instead.
The commands we’ve covered so far help manage services within the current session, but if you want a service to start automatically when the system boots, you’ll need to enable it.
Systemctl Enable Service (systemd enable service)
To configure a service to launch during startup, run:
$ sudo systemctl enable application.service
This command creates a symbolic link from the service’s file—usually located in /lib/systemd/system/ or /etc/systemd/system/—to a directory that systemd scans at boot for auto-start services (commonly something like /etc/systemd/system/some_target.target.wants).
Systemctl Disable Service
To disable a service from starting at boot, use:
$ sudo systemctl disable application.service
This removes the symbolic link, so systemd will no longer automatically launch the service.
Keep in mind that enabling a service only schedules it to start at boot—it does not immediately start the service in the current session. If you want to enable the service and start it right away, you need to run both enable and start.
To check whether a service is running and view some basic information about it, you can use:
$ systemctl status application.service
This displays details such as whether the service is active, how long it’s been running, and the most recent log entries related to it.
For example, if you check the status of docker, you might see something like:
This summary gives you a quick health check of the service and highlights any issues if they exist.
If you only want to check whether a service is running, you can use:
$ systemctl is-active application.service
This command outputs either active or inactive. It also returns an exit code—0 means the service is active, which can be useful if you’re automating checks in a script.
To find out if a service is set to start at boot, run:
$ systemctl is-enabled application.service
This will return either enabled or disabled, and like before, the command’s exit code can indicate the result.
Finally, to check if a service has failed, meaning it encountered an error when starting or running, use:
$ systemctl is-failed application.service
This returns failed if something went wrong, or active if it’s running properly. If the service was intentionally stopped, you might see inactive or unknown. An exit code of 0 signals failure, while 1 indicates any other state.
So far, we’ve looked at commands that help manage individual services, but if you want to get a broader look at the system as a whole, systemctl also offers commands for that.
To see which units are currently running or active, you can use the list-units command:
$ systemctl list-units
This will display all units that are actively being managed by systemd at the moment. The output will look something like this:
Here’s what each column represents:
By default, this only shows units that are currently active. In fact, running systemctl with no additional arguments produces the same output.
$ systemctl
If you want to see every unit that systemd has either tried to load or currently has in memory — even if they aren’t running right now — you can add the --all flag:
$ systemctl list-units --all
This will include units that ran and then stopped, or even units that systemd tried to load but couldn’t find.
To narrow this down, you can filter by specific states. For instance, if you only want to see inactive units, you can run:
$ systemctl list-units --all --state=inactive
You can also filter by type. To only show services, for example:
$ systemctl list-units --type=service
The commands above only show units that systemd has interacted with — either by loading them or attempting to run them. To see all available unit files on the system (whether or not systemd has touched them), use:
$ systemctl list-unit-files
This lists all unit definition files found in the systemd directories. This includes files systemd never attempted to load. The output looks like this:
There are two columns:
Here’s what those states mean:
This gives you a complete inventory of all units on the system, whether systemd actually tried to use them or not.
So far, we’ve mainly focused on starting and stopping services, as well as viewing basic details about systemd units and their files. However, systemd provides several commands to dig deeper into unit information and control them more precisely.
To see the actual unit file that systemd has loaded into memory, you can use the cat command (this was introduced in systemd version 209). For example, to view the unit file for the apache2 service, you would run:
$ systemctl cat apache2.service
This command outputs the contents of the unit file currently known to systemd. This is particularly useful if the file has been recently modified or if custom overrides have been applied. The displayed content reflects the file’s live state as systemd sees it.
If you want to check what other units a particular service relies on, the list-dependencies command is helpful. For example, to see what the sshd service depends on, you would run:
$ systemctl list-dependencies sshd.service
This displays a tree-like view of units that sshd.service either needs directly or wants (optional dependencies). Systemd targets, which are special groupings of units representing system states, will show their own internal dependencies as well.
To show all recursive dependencies, you can include the --all option:
$ systemctl list-dependencies --all sshd.service
You can also reverse this view to find out which units depend on the specified service. To do this, add the --reverse flag:
systemctl list-dependencies --reverse sshd.service
If you want to check which units are configured to start before or after the service in question, you can use these options:
systemctl list-dependencies sshd.service --before
systemctl list-dependencies sshd.service --after
Each unit has many properties controlling how systemd handles it. To see all of these properties for a particular unit, use the show command. This presents detailed unit data in a key=value format:
systemctl show sshd.service
This will print out dozens of properties, including what targets this unit belongs to, any conflicts with other units, and its dependency relationships.
If you only want to see one particular property, you can filter with the -p option. For instance, to check which units the sshd service conflicts with:
systemctl show sshd.service -p Conflicts
Sometimes, simply stopping or disabling a service isn’t enough — you might want to completely prevent it from starting under any circumstances. This is where masking comes in. When a unit is masked, systemd links it to /dev/null, effectively blocking it from being started manually or automatically.
To mask a unit, run:
$ sudo systemctl mask apache2.service
If you check all unit files after this, you’ll see that apache2.service is marked as "masked":
$ systemctl list-unit-files
If you attempt to start a masked service, systemd will refuse and show an error:
$ sudo systemctl start apache2.service
To allow the service to start again, unmask it with:
$ sudo systemctl unmask apache2.service
This removes the block and restores the unit to its regular state, where it can once again be started or enabled like any other service.
Although explaining the exact structure and syntax of unit files goes beyond this guide, systemd provides built-in tools to help you make changes directly when needed. These editing features were introduced in systemd version 218.
The edit command allows you to make changes to a unit file through a simple interface. By default, this command opens a blank override file specifically for the unit you want to modify. For example, to create an override for nginx.service, you would use:
$ sudo systemctl edit nginx.service
This creates a directory under /etc/systemd/system with the unit’s name followed by .d — for example, nginx.service.d. Inside that directory, systemd places a file called override.conf, where you can add your custom configuration.
When the service starts, systemd combines this override file with the main unit file, giving priority to any settings defined in the override. This makes it easy to tweak specific options without directly editing the original file.
If you want to modify the entire unit file instead of creating a small override, you can use the --full option:
$ sudo systemctl edit --full nginx.service
This command loads the current complete file into your editor, allowing you to make all necessary changes. Once you save and close the editor, systemd saves the modified file to /etc/systemd/system, which takes precedence over the default file found in /lib/systemd/system.
If you ever need to undo your changes, you can simply delete either the override directory or the custom unit file itself.
To remove an override directory:
$ sudo rm -r /etc/systemd/system/nginx.service.d
To remove a fully customized unit file:
$ sudo rm /etc/systemd/system/nginx.service
Once the files are deleted, you need to reload systemd so it forgets the removed files and returns to using the original system unit file:
sudo systemctl daemon-reload
This ensures systemd no longer looks for or applies the changes you removed.
In systemd, targets represent specific system states, similar to traditional runlevels in older init systems. These targets are defined as special unit files ending with .target, and they work by grouping other units together to achieve the desired state.
The system boots into a default target, which determines the system state after startup. You can check the current default target with:
$ systemctl get-default
To change the default target, for example, to a graphical desktop environment, use:
$ sudo systemctl set-default graphical.target
To see all available targets on the system:
$ systemctl list-unit-files --type=target
To view only currently active targets:
$ systemctl list-units --type=target
You can switch the system to a different target, stopping all unrelated services and starting only the ones required for the new target. This is done using the isolate command.
For example, to switch from a graphical desktop to a command-line only environment:
$ sudo systemctl isolate multi-user.target
Before isolating, it’s useful to check what services a target depends on:
$ systemctl list-dependencies multi-user.target
This ensures you don’t accidentally stop important services.
Systemd provides dedicated shortcuts for handling essential system events such as shutting down, rebooting, or entering rescue mode. These shortcuts trigger the appropriate targets and notify all logged-in users about the event, adding an extra layer of communication.
$ sudo systemctl rescue
This behaves similarly to isolating rescue.target, but with the added benefit of informing active users.
$ sudo systemctl halt
$ sudo systemctl poweroff
$ sudo systemctl reboot
Most Linux systems also provide traditional commands that are linked directly to systemd, so you can often just type:
$ sudo reboot
These commands integrate seamlessly with systemd, ensuring proper communication and clean handling of system events.
Securing systemd services is a crucial step to protect your system from attacks, unauthorized access, and accidental damage. Below is a streamlined approach to hardening services using systemd.
Each service managed by systemd has a corresponding unit file, which defines how the service runs, including startup processes, access permissions, and resource limits. These files are usually stored in /etc/systemd/system/ and can be customized to improve security.
We learned from this article how to use systemctl command. The systemctl is the primary tool for managing services and system states in systemd. It serves as the main interface for interacting with the system’s core process. However, systemd also includes additional tools like journalctl for viewing logs and loginctl for managing user sessions. Understanding these related tools will help you manage your system more effectively.
Is your business outgrowing the limits of VPS hosting? Upgrade to the power and performance of a dedicated server from BlueServers!
Take your hosting to the next level — Explore Dedicated Servers at BlueServers today!
Start for free and unlock high-performance infrastructure with instant setup.
Your opinion helps us build a better service.