1. Overview
Services are programs that often run in the background. Another feature of services is that they usually start during the system’s initialization process. When they do, the init program that’s responsible for initializing the system also starts these required services. Furthermore, there’s more than one implementation of the init program. Most of these implementations provide a way to list all services and their status.
In this tutorial, we’ll examine how we can list services and their status in popular service managers. We’ll also see how we can find the status of a service when we’re not aware of its name.
2. SysV Initialization
This is the older initialization process, that was once common. Services are started with initialization shell scripts, located under the /etc/init.d directory.
2.1. The /etc/init.d Directory
So, if we don’t know the exact name of a service under SysV, one way to find it is to search for a script in the /etc/init.d directory:
$ ls -al /etc/init.d | grep ssh
-rwxr-xr-x 1 root root 3939 Mar 30 2022 ssh
Here, we listed all files under the /etc/init.d directory and filtered the output using grep and the ssh string. Indeed, we can see in the output that there’s a script named ssh. This is evidence that our system has an SSH service. Furthermore, we can often query the status of the service with the status option:
$ /etc/init.d/ssh status
sshd is running.
Indeed, the script printed that the service is running.
2.2. The service Command
The service command is an interface for managing services. As a matter of fact, service is also a shell script. Under the hood, it leverages the shell scripts of the /etc/init.d directory that we saw earlier. Moreover, it has a handy option called –status-all that outputs a list of all system services and their status.
The –status-all option runs all scripts under /etc/init.d with the status option and prints the result to the standard output:
$ service --status-all
[ - ] nginx
[ + ] ssh
[ ? ] ubuntu-fan
...
As we can see, the –status-all option printed a list of services. Each service has a special sign in front of it within brackets:
- [+]: running
- [-]: not running
- [?]: status option not implemented
So, in the above example, we have an nginx service that isn’t running, an ssh service that’s running, and an ubuntu-fan service that hasn’t implemented the status option in its initialization script.
Importantly, the service command has evolved to also function with the systemd initialization system that we’ll explore in the following sections. In fact, the SysV initialization system is largely substituted by systemd. Nevertheless, we can still use the service command to find the status of a service. This is true because service checks if the system is started with systemd and calls the appropriate systemd command to get the status.
3. The systemd System Manager
Currently, most Linux distributions use systemd. The systemd manager uses special configuration files instead of shell scripts. The filename of these files ends with the string service. This differentiates them from other units that systemd administers like sockets, mounts, and others.
3.1. Configuration Files
Interestingly, systemd scans many directories to find service configuration files. Examples are /etc/systemd/system and /run/systemd/system. To have a grasp of the contents, let’s list the /etc/systemd/system directory:
$ ls /etc/systemd/system | grep .service$
...
nginx.service
snap.lxd.activate.service
snap.lxd.daemon.service
sshd.service
syslog.service
vmtoolsd.service
Here, we filtered the output to display files that end with the service suffix. In this case, the name of the file corresponds to the name of the service.
3.2. The systemctl list-units Command
Instead of searching in directories to find a service, a better way is to use the systemctl command. The list-units option is useful for printing the unit managed by systemd:
$ systemctl list-units --type=service | grep ssh
ssh.service loaded active running OpenBSD Secure Shell server
Here, we’ve used the –type option to print units of type service only. Furthermore, we’ve filtered services with the grep command and the ssh string. Indeed, there’s an ssh.service unit that’s loaded, active, and running. In addition, the command printed a small description of the service.
3.3. The systemctl status Command
An alternative way is to use the status option of the systemctl command:
$ systemctl status ssh
● ssh.service - OpenBSD Secure Shell server
Loaded: loaded (/lib/systemd/system/ssh.service; enabled; vendor preset: enabled)
Active: active (running) since Fri 2023-04-07 16:03:37 EEST; 2 days ago
Docs: man:sshd(8)
man:sshd_config(5)
Main PID: 1262 (sshd)
Tasks: 1 (limit: 1053)
Memory: 4.6M
CGroup: /system.slice/ssh.service
└─1262 sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups
Apr 07 16:11:34 handsome-tattler sshd[1746]: Accepted publickey for ubuntu from 172.27.192.1 port 56487 ssh2: RSA SHA256:mUySiSiRXHAP2ZJWNJOWhmnZwW95e1apeRPpf818Zbg
Apr 07 16:11:34 handsome-tattler sshd[1746]: pam_unix(sshd:session): session opened for user ubuntu by (uid=0)
...
We can see that the command printed a lot of information to the standard output:
- if the service is loaded in memory, we get its unit configuration file path current loading status (enabled), meaning that it’s started on boot
- activation (active) and run (running) status together with the start date
- manual information
- process ID
- tasks
- memory consumption
- cgroup that the service belongs to
- service output log
In case we know the process ID and not the name of a service, we can still use the status option:
$ systemctl status 1262
● ssh.service - OpenBSD Secure Shell server
Loaded: loaded (/lib/systemd/system/ssh.service; enabled; vendor preset: enabled)
Active: active (running) since Fri 2023-04-07 16:03:37 EEST; 3 days ago
...
Indeed, we can see that the status option works perfectly with the process ID of the service.
4. The OpenRC Service Manager
OpenRC is another service manager, usually found in Gentoo distributions. Moreover, it’s available for installation from Debian repositories.
The OpenRC service manager has the rc-status command to display the status of all services:
$ rc-status --all
...
Runlevel: sysinit
udev [ stopped ]
procps [ stopped ]
networking [ stopped ]
hwclock.sh [ stopped ]
kmod [ stopped ]
cgroups [ stopped ]
Runlevel: shutdown
Runlevel: recovery
...
Here, we can see that services are grouped by the runlevel the system starts them at. Furthermore, we can see the status of the service in brackets.
Another command that we can use to get the status of a service is the rc-service command with the status option:
$ rc-service ssh status
sshd is running.
In this example, we entered the name of a service to get its status. So, we should still know the exact name of the service beforehand.
5. Determining How the System Is Initialized
Determining how the system is initialized isn’t trivial. The problem boils down to determining if the init program is systemd, SysV, or something else. One way is to find the init program file and check if it’s a link to another file. Usually, the init program is located at /sbin/init:
$ ls -al /sbin/init
lrwxrwxrwx 1 root root 20 Mar 2 14:58 /sbin/init -> /lib/systemd/systemd
Here, we can see that the init program points systemd. So, in this case, our system uses systemd.
Another way is to check the init process with pstree. The pstree command prints a tree with the running processes of a system. The root of the tree is the init process:
$ pstree
systemd─┬─ModemManager───2*[{ModemManager}]
├─accounts-daemon───2*[{accounts-daemon}]
├─2*[agetty]
├─atd
...
Here, the pstree command clearly states that the init process runs systemd.
6. Conclusion
In this tutorial, we learned how we can find the status of a service that we’re not aware of its name. In particular, we examined three systems:
- SysV
- systemd
- OpenRC
Finally, we saw two ways to determine how a Linux system is initialized.