How to Use Systemctl for Managing systemd Units and Services?

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.

Managing Services with Systemctl

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.

Starting and Stopping Services Using Systemctl

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

Systemctl Restart 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.

Enabling and Disabling Services with systemctl

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.

Checking Service Status

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:

how to use systemctl for managing systemd units and services?

This summary gives you a quick health check of the service and highlights any issues if they exist.

Checking Specific Service States

If you only want to check whether a service is running, you can use:

$ systemctl is-active application.service

how to use systemctl for managing systemd units and services?

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.

Viewing Overall System State (Systemctl List Services)

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.

Viewing Active Units 

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:

  • UNIT: The actual name of the unit.
  • LOAD: Whether systemd has successfully read and loaded the unit file into memory.
  • ACTIVE: A general indicator of whether the unit is running properly.
  • SUB: A more detailed lower-level status that depends on the specific type of unit.
  • DESCRIPTION: A brief summary explaining the unit’s purpose.

By default, this only shows units that are currently active. In fact, running systemctl with no additional arguments produces the same output.

$ systemctl

Showing All Units (Active and Inactive)

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

how to use systemctl for managing systemd units and services?

Listing All Unit Files (Whether Loaded or Not)

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

how to use systemctl for managing systemd units and services?

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:

  • UNIT FILE: The name of the unit file.
  • STATE: Whether the unit file is enabled, disabled, static, or masked.

Here’s what those states mean:

  • enabled: The unit is set to automatically start when needed.
  • disabled: The unit won’t start automatically but can be started manually.
  • static: This unit doesn’t have an “install” section, meaning it’s not designed to be enabled directly — instead, it’s meant to be triggered by dependencies.
  • masked: The unit has been explicitly disabled in a way that prevents it from being started under any circumstances (more on that in the next section).

This gives you a complete inventory of all units on the system, whether systemd actually tried to use them or not.

How to Work with Systemd Units?

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.

Viewing a Unit’s File

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

how to use systemctl for managing systemd units and services?

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.

Checking Unit Dependencies

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

Viewing Unit Properties

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

Masking and Unmasking Units

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.

How to Edit Unit Files Using systemctl?

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.

Editing with systemctl

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.

Editing the Full Unit 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.

Removing Custom Changes

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.

Managing System States with Targets

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.

Default Target (Boot Target)

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

Listing and Viewing Targets

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

Switching Targets (Isolating)

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.

Using Systemctl Shortcuts for Key Events

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.

To enter rescue mode (single-user mode), you can run:
$ sudo systemctl rescue

This behaves similarly to isolating rescue.target, but with the added benefit of informing active users.

To halt the system (stop all processes without powering off):
$ sudo systemctl halt

To perform a full system shutdown, use:
$ sudo systemctl poweroff

To reboot the machine:
$ 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.

Improve Service Security with systemd

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.

1. Understand Service Unit Files

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.

2. Limit Service Privileges

  • Run as a non-root user: Assign a dedicated user and group for each service rather than running it as root. This reduces the risk if the service is compromised.

3. Use Built-in systemd Security Options

  • Isolate temporary directories: Enable PrivateTmp so the service gets its own temporary space, preventing cross-service data leaks.
  • Restrict system access: Set ProtectSystem to limit what parts of the filesystem the service can access. Use ProtectHome to block access to user home directories.
  • Control directory access: Use ReadOnlyPaths to mark directories as read-only, and ReadWritePaths to define where the service can write data.

4. Set Resource Limits

  • Restrict CPU and memory usage: Use CPUQuota to cap how much CPU the service can use, and MemoryLimit to restrict how much memory it can consume. This helps prevent excessive resource consumption, whether intentional or due to bugs.

5. Manage Network Access

  • Control network exposure: Use RestrictAddressFamilies to limit which address families the service can use (for example, disabling AF_INET if network access isn’t required).
  • Use IPAddressAllow and IPAddressDeny to create network access rules if the service needs to communicate.

6. File Ownership and Permissions

  • Ensure correct file permissions: The files and directories used by the service should have proper ownership (via chown) and restrictive permissions (via chmod). Only the necessary user should have write access to configuration files, logs, and data.

7. Stay Updated and Monitor Logs

  • Regularly apply updates: Keep both the system and service software updated to receive the latest security patches.
  • Monitor service activity: Use journalctl to review the service’s logs for errors, suspicious activity, or security-related messages.

Conclusion

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!

  • Fully customizable and built to scale with your needs
  • Complete server control in a dedicated environment
  • Enjoy unlimited traffic for your growing business

Take your hosting to the next level — Explore Dedicated Servers at BlueServers today!

 

Blog