This is actually quite a difficult problem. One of the major difficulties is that the places where one most often wants to do this are the places where it's quite likely that one will be in the middle of installing or changing stuff. Another is that there's a subtle but very important difference between the system management toolset that is installed, the system management toolset that is running right now, and the system management toolset that will run at next boot.
Determining what is installed one does with a package manager, of course. But this is complicated by the fact that several systems can be installed side by side.
On Debian Linux, for example, one can install the systemd package, but it is the installation of the separate systemd-sysv package that makes it the active system. The intention is that the systemd and sysvinit packages can be installed simultaneously. Indeed, the Debian Linux crowd has taken steps in Debian 8 to shift towards every program having a different name (/lib/sysvinit/init
, /lib/systemd/systemd
, /sbin/runit-init
, /sbin/minit
, /sbin/system-manager
, and so forth) for this very reason, that the "non-activating" packages don't conflict on the name /sbin/init
. /sbin/init
is then a symbolic link to whichever was configured to run at next boot by an "activating package".
Determining what is running now and ready to run next one can only do with a series of toolset-specific tests, with varying degrees of risk from false positives, and with varying degrees of documentation. To check for what system manager is running right now, specifically, one really has to look at the process list or at the various APIs that system managers publish. But this isn't wholly without pitfalls.
General non-starters
Let's start with things that definitely will not work.
/proc/1/exe
will point to the same /sbin/init
when either upstart or System 5 init
are running right now. And on some systems, it's also /sbin/init
when systemd is running.The Debian Linux crowd wanted to shift towards every program having a different name, as mentioned earlier. But this is Debian-specific, far from universal, and doesn't really help when the program is invoked as /sbin/init
(by the initramfs phase of the bootstrap) anyway. Only Felix von Leitner's minit is actually packaged by Debian 8 to be invoked with its own name.
- The existence of the control API file
/dev/initctl
isn't specific to System 5 init
. systemd has a (non process #1) systemd-initctl
server that serves this. Joachim Nilsson's finit
serves it too. (Just to make things extra fun, on Debian it's now located at /run/initctl
. See https://superuser.com/a/888936/38062 for details.)
- systemd, upstart, System 5
rc
, and OpenRC all process /etc/init.d/
, for backwards compatibility in the case of the former two. Its existence does not indicate the presence of any given system.
Detecting System 5 init
Ironically, as explained at https://unix.stackexchange.com/a/196197/5132 , one way on Debian Linux at least for detecting the absence of System 5 init
is the absence of /etc/inittab
. However:
- This is an side-effect of Debian's way of packaging things like
/etc/inittab
.
- One part of the overall problem is that
/etc/inittab
sticks around if System 5 init
was used at any point in the past, because uninstalling the package does not delete its configuration file. (This has been a sizeable problem for Debian 8 work, since there are several packages in Debian 7 which install themselves by adding entries to /etc/inittab
.)
- It's an inverted test.
Detecting systemd
To check for systemd as the running system manager in the "official" manner, one checks for the existence of /run/systemd/system
. This is a directory, in /run
, that systemd itself creates at boot, and that other system managers are unlikely to create.
But that's merely unlikely. This check is already broken, because uselessd creates this directory too.
Other, unofficial, checks won't work:
- systemd publishes a whole RPC API over D-Bus, which even contains a version name and number; but:
- The existence of
/run/systemd/private
is similarly not guaranteed and similarly duplicated by uselessd.
Detecting nosh
The system-manager
in nosh creates a /run/system-manager
directory. But this shares the weaknesses of the equivalent systemd check.
Further non-starters:
- The nosh
system-manager
by design doesn't create pipes or sockets in the filesystem, and doesn't have an RPC API in the first place.
- The nosh
service-manager
conventionally has an API socket at /run/service-manager/control
, but one can run the nosh service manager under some other system manager; so this doesn't tell one what system manager is running as process #1. In any case, it doesn't set that name itself; whatever invoked it does.
- The existence of a nosh version string, emitted by
system-control version
, systemctl version
(if one has the systemd compatibility shims installed) and initctl version
(if one has the upstart compatibility shims installed) only indicates the presence of the toolset, as these tools make no query of the running system.
Detecting upstart
Upstart's own initctl
makes an API call over D-Bus, and the official check is to both check that one can run initctl
and that its output contains the string "upstart" somewhere.
But, like the systemd API:
- There's no guarantee that the API will be around tomorrow or not changed at whim.
- There's no guarantee that some compatibility shim doesn't exist or won't exist in the future.
Indeed, there already is one compatibility shim. nosh has an upstart compatibility package that provides shims for the upstart initctl
, start
, stop
, and status
commands. Luckily (although this was intentional), the initctl
shim does not emit the word "upstart".
root ~ #initctl version
nosh version 1.14
root ~ #
dpkg -l
,yum
or whatever package manager be enough to identify the init system?dpkg -l|grep systemd
gives me an answer when asked in Debian whiledpkg -l|grep upstart
doesn't, so I can say that my Debian install is using systemd instead any other init system. I'm not saying it is the answer, only that testing debian pakages can give an answer, but I can't say about red hat, suse or others. I'm guessing that if only one init system is installed by default then querying packages may give an answer.strings
says about it? For my Ubuntu box here, the results contain "upstart", now it's just data gathering ;)