The service files have .service extensions and contain the instructions that are required by systemd to manage a service.
The systemd init system manages the system initialization using the Unit. A unit is an object that performs a task or action, such as managing a service, which involves controlling and monitoring it. These units are essentially files called service files that include unit dependencies and commands. These files are crucial to efficiently controlling the background processes, and managing resources.
In the guide, I will be exploring the systemd service file, its structure, and the main directives that control the service.
When working with systemd, the terms systemd service file and systemd unit file are often used interchangeably because technically they refer to the same thing.
What is Systemd Service File
On Linux, the systemd manages the services using the service files that contain the configuration instructions so the systemd can understand and execute.
To list the units, use systemctl with the –list-units command.
To read the service file of any service, use the cat command with the file path.
For instance, to see the service file of ssh.service use the given command.
Anatomy of Systemd Service File
Generally, systemd service unit files contain three sections.
- Unit
- Service
- Install
A service-specific unit file will have a specific section called the Service section.
Note that the service is just a type of unit. A unit can have different types such as socket, device, mount, automount, swap, target, timer, slice, and scope. These sections are placed in between the Unit and Install sections. The file extension will also be replaced with the respective unit type, for example, a socket unit type will have a .socket file extension.
Note: In this guide, I will focus on the service unit type because of its wide usage by administrators and developers.
These sections are enclosed in the square brackets ([]). Each section contains a relevant instruction set. A general structure of a service file is given below.
Directive1=Instruction 1
Directive2=Instruction 2
[Service]
Directive1=Instruction 1
Directive2=Instruction 2
[Install]
Directive1=Instruction 1
Directive2=Instruction 2
The order of the sections can be changed; however, the above-mentioned order is generally followed.
[Unit] Section
The unit section contains the description of the unit and unit dependencies. This section, by convention, is placed at the top of the service file. Commonly used directives are listed below:
Directive | Description |
Description | This directive is used to mention the name of the service. The length of the description must not exceed 80 characters. |
Documentation | This directive contains the man page or URL of the service. |
Requires | This directive is used to mention the dependency on the current service. If the activation of this dependency service is not performed, the current service will not be initiated. |
Wants | This directive is used to mention the dependency on the current service. However, this dependency service is not required to be activated to run the current service. |
Before | After the current unit has been activated, the service mentioned in this directive will be started. |
After | Before the current unit has been activated, the service mentioned in this directive will be started. |
BindsTo | This directive links the current service to the mentioned service. If the linked service restarts, the current services will also restart. |
Apart from these directives, there are two more directives; Condition and Assert. Many services require specific system conditions to successfully run, and these directives are used to mention the conditions.
[Install] Section
This section is not mandatory and is only necessary when a service requires activation or deactivation on boot. Moreover, it is also to mention the alias service. Commonly used directives for the Install section are listed below:
Directive | Description |
WantedBy | This directive sets the run-level* target of the service. If a target is set to multi-user.target then the service will be enabled on this run-level. |
RequiredBy | This directive bears resemblance to WantedBy, however, even without the dependency mentioned in the directive, the service will be enabled. |
Alias | This directive is used to enable the service with another name. A symlink is created with this name when the service is enabled. |
Mostly, the multi-user.target is used as WantedBy parameter. But what is multi-user.target?
The multi-user.target represents the system state ready to accept non-graphical multiple-user sessions. It is the state before launching the GUI.
There are different run levels of the system, let’s learn about the function of these run levels.
In systemd, the services are grouped based on run levels, which are called targets. Each run-level has a file with .target extension in the /etc/systemd/system directory. A service will run based on the state of the run level.
Run Level | Targets | State | Files |
0 | poweroff | Shut down & power off | poweroff.target |
1 | rescue | Starts the rescue shell | rescue.target |
2,3,4 | multi-user | Starts multi-user non-GUI shell | multi-user.target |
5 | graphical | Establishes multi-user GUI shell | graphical.target |
6 | reboot | Shut down & restart | reboot.target |
[Service] Section
This section comprises the configuration settings for the service. The primary configuration of this section is defining the type and commands to be executed at the start of the service. Type and ExecStart are the main directives used to set up a service.
Different types of the service are listed in the following table.
Service Type | Description |
simple | It is the default type when the type or Busname is not mentioned and only ExecStart is mentioned. The systemd executes the main process first and then follow-up units. |
forking | This type is used to keep the service running even if the parent service is closed. It forks a child process after the closing of the parent process. |
oneshot | The systemd executes the main process first and when the main process exits the follow-up units will start. |
dbus | The service with dbus is used to communicate with another process on the bus. If the bus name is mentioned, then the process will be activated after the bus name is acquired. |
notify | The service will notify when starting the process. The systemd will proceed to the follow-up units after the notification is issued. |
idle | It holds the service till all the active jobs are dispatched; primarily useful to improve the console output. |
The commonly used directives in the Service section are mentioned below:
Directive | Description |
ExecStart | It keeps the full path of the command to be executed to begin the process. |
ExecStartPre | It keeps the commands that should be executed before the main process begins. |
ExecStartPost | It keeps the commands that should be executed after the main process begins. |
ExecReload | It keeps the command to reload the service configuration. |
Restart | To automatically restart the service in circumstances such as on-failure, on-success, on-abnormal, on-abort, and on-watchdog. |
RestartSec | To keep the number of seconds after which the service will automatically restart. |
The ExecStart is one of the crucial directives used in the Service section. It contains the full path of the executable that the service will execute on invoking.
Conclusion
A systemd service file is a configuration file that is structured with directives and commands so they can be managed by systemd. These files contain instructions indicating how a service is managed by systemd. In this guide, I covered how to access a systemd service file, its sections, and directives that manage the services. To learn more about service file instructions, please read the official documentation guide found here.