This question already has an answer here:

Is there a simple way to find out which initsystem is being used e.g by a recent Debian wheezy or Fedora system? I'm aware that Fedora 21 uses systemd initsystem but that is because I read that and because all relevant scripts/symlinks are stored in /etc/systemd/. However, I'm not sure about e.g Debian squeeze or CentOS 6 or 7 and so on.

Which techniques exist to verify such initsystem?

marked as duplicate by terdon Apr 15 '15 at 11:39

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • Since default installation will only have one init system, wouldn't dpkg -l, yum or whatever package manager be enough to identify the init system? – YoMismo Apr 14 '15 at 14:20
  • 1
    dpkg -l|grep systemd gives me an answer when asked in Debian while dpkg -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. – YoMismo Apr 14 '15 at 14:32
  • 2
    I should also mention there are other init systems including BSD. – hildred Apr 14 '15 at 14:43
  • 2
    Very handwavy, couldn't you see what process has pid 1 and what strings says about it? For my Ubuntu box here, the results contain "upstart", now it's just data gathering ;) – Ulrich Schwarz Apr 14 '15 at 15:37
  • 1
    Strictly speaking, this is not a duplicate. This question asked about Linux operating systems, specifically. The other question included BSDs, MacOS, Solaris, and minix. None of these answers, including mine, address those. With good reason: it would make the already long answers even longer still. Plus it was not the question asked, of course. – JdeBP Apr 15 '15 at 12:06
up vote 52 down vote accepted

You can poke around the system to find indicators. One way is to check for the existence of three directories:

  • /usr/lib/systemd tells you you're on a systemd based system.

  • /usr/share/upstart is a pretty good indicator that you're on an Upstart-based system.

  • /etc/init.d tells you the box has SysV init in its history

The thing is, these are heuristics that must be considered together, possibly with other data, not certain indicators by themselves. The Ubuntu 14.10 box I'm looking at right now has all three directories. Why? Because Ubuntu just switched to systemd from Upstart in that version, but keeps Upstart and SysV init for backwards compatibility.

In the end, I think the best answer is "experience." You will see that you have logged into a CentOS 7 box and know that it's systemd. How do you learn this? Playing around, RTFMing, etc. The same way you gain all experience.

I realize this is not a very satisfactory answer, but that's what happens when there is fragmentation in the market, creating nonstandard designs. It's like asking how you know whether ls accepts -C, or --color, or doesn't do color output at all. Again, the answer is "experience."

  • 3
    @val0x00ff: That's actually why I asked the question in the comment above. When you start doing automatic probing for system features, you have to do so very carefully if you want it to actually be portable. The Ubuntu 14.10 lesson is that you have to do them in the order listed above. This doesn't tell you that Ubuntu 15.10 isn't going to do something else that will break your script, though. – Warren Young Apr 14 '15 at 15:27
  • 4
    The mere presence of an artifact is not enough to claim that it is in use. On an Ubuntu server I manage, systemd is installed, yet the machine is still using upstart. – sleblanc Apr 15 '15 at 1:03
  • 2
    @val0x00ff Also possibly useful to know is the fact that all three of the init systems you know can and will honor standard LSB init.d scripts if they're found... – Shadur Apr 15 '15 at 9:16
  • 13
    This can also be achieved with simple ps -p 1 command, the output should point your to init|upstartd|systemd process, its its init then do /sbin/init --version. – askb Mar 3 '16 at 8:20
  • 3
    This is a terrible answer. Any question could be answered with "experience" but doing so is the epitome of condescension. Your experience gives you an algorithm that you employ to find the answer to this question. For the ls -c bit, it may be as simple as trying ls -c and seeing if it errors. For this question, there must be some way in which the system records for itself which init system it is going to use. Some configuration file somewhere that can be checked. Your "experience" tells you what it is. Unless you're willing to share it, you shouldn't be posting answers. – Daniel Bingham Oct 11 '16 at 18:11

The init process is always assigned PID 1. The /proc filesystem provides a way to obtain the path to an executable given a PID.

In other words:

nathan@nathan-desktop:~$ sudo stat /proc/1/exe
  File: '/proc/1/exe' -> '/sbin/upstart'

As you can see, the init process on my Ubuntu 14.10 box is Upstart. Ubuntu 15.04 uses systemd, so running that command instead yields:

nathan@nathan-gnome:~$ sudo stat /proc/1/exe
  File: '/proc/1/exe' -> '/lib/systemd/systemd'

If the system you're on gives /sbin/init as a result, then you'll want to try statting that file:

nathan@nathan-gnome:~$ sudo stat /proc/1/exe
  File: '/proc/1/exe' -> '/sbin/init'
nathan@nathan-gnome:~$ stat /sbin/init
  File: ‘/sbin/init’ -> ‘/lib/systemd/systemd’

You can also execute it to find out more:

[user@centos ~]$ /sbin/init --version
init (upstart 0.6.5)
Copyright (C) 2010 Canonical Ltd.
  • 2
    But, RHEL 6 (and therefore CentOS, Scientific Linux, etc.) uses upstart, and stat /proc/1/exe yields File: '/proc/1/exe' -> '/sbin/init', which doesn't tell you much. – mattdm Apr 14 '15 at 18:46
  • @mattdm: that's odd - on Fedora 21, I get File: '/proc/1/exe' -> '/usr/lib/systemd/systemd'. – Nathan Osman Apr 14 '15 at 18:50
  • 4
    So, actually, from the point of view of the use case, it may actually be more correct to treat EL6 as SysVInit, even though it is Upstart underneath — if you're dropping new services into place, traditional SysVInit scripts are the preferred approach. – mattdm Apr 14 '15 at 18:55
  • 2
    I also get ‘/proc/1/exe’ -> ‘/sbin/init’ on Debian. – terdon Apr 15 '15 at 11:37
  • 2
    for what it's worth, stat /sbin/init provides File: sbin/init under Ubuntu 14.04 – Elder Geek May 5 '15 at 15:50

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 ~ #
  • What might one want to do with this information for which uselessd is not compatible with systemd? A brief look at that site seems to show that it is a "cut-down systemd". – Random832 Apr 14 '15 at 20:29
  • 1
    +1, but a couple of niggles: 1) The presence of /etc/init.d does indeed not tell you that SysVinit is the main init system, but it does tell you that you aren't on a traditional BSD box. Put it last in the list of checks, after you've ruled out all the other options. 2) The fact that uselessd mimics systemd in some ways is not necessarily a problem. If you're deciding whether to install a *.service file vs an init script, a check that happens to lump systemd and uselessd together is fine. If you're trying to use one of the features uselessd purposely does not provide, then it's a problem. – Warren Young Apr 15 '15 at 9:36
  • If you look carefully, you'll see that the question doesn't extend to BSDs. ☺ – JdeBP Apr 15 '15 at 12:02
  • @JdeBP: Yes, but that's because it's a rather blinkered question, which is why there are so many upvoted answers. There really isn't a simple, good answer to this question. The "right" answer will depend on why one is really asking the question, and what conditions apply. Pointing out holes where the existing answers fail is worthwhile. It reminds me of early Autoconf documentation that pushed you towards if test x"$y" = "x" instead of if [ -z "$y" ] because the latter didn't work on the original Bourne shell. When striving for wide portability, you need to be aware of all the traps. – Warren Young Apr 15 '15 at 18:25
  • A question that doesn't fulfil our desire to cover every operating system covered by the site in one massive answer, but limits itself to the several Linux systems that the questioner actually intends to use, is not really "blinkered". There's no simple answer not because the question doesn't ask about operating systems that you want to talk about, but because it's a difficult thing to do (and not just for system management toolsets) . I wrote that above, you'll find. ☺ – JdeBP Apr 15 '15 at 19:28

On RPM-based systems, you can query the RPM database to see what package provides /sbin/init. For example:

fedora:~$ rpm -qf /sbin/init
systemd-216-24.fc21.x86_64

centos:~$ rpm -qf /sbin/init
upstart-0.6.5-12.el6_4.1.x86_64

opensuse:~$ rpm -qf /sbin/init
systemd-sysvinit-44-10.1.1.i586

If you just want the package name, and not version, you could add the --qf option to RPM ("queryformat", not to be confused with the other -qf with one hyphen, which means "query: file"), like this: rpm --qf '%{name}\n' -qf /sbin/init.

On Debian-based systems, you can do a similar thing with dpkg:

ubuntu:~$ dpkg -S /sbin/init
upstart: /sbin/init

And, most package managers will have a similar command. Of course, then you need to know what package manager your distro uses, which might just be trading one problem for another.

Also, on some distros, it's possible that /sbin/init is not the right file to look at, most likely because init=/something/else is given on the kernel command line. Another possibility would be that /sbin/init is a symlink owned by some helper package tasked with switching between init systems, and not owned by any of them directly. One or both of these may be the case on Arch (although I don't have an Arch box handy to check right now).

  • 2
    wow I didn't know about the -S option. This gives some more insights about the initsystem. Thanks a bunch! – Valentin Bajrami Apr 14 '15 at 17:02
  • 1
    "Also, on some distros, it's possible that /sbin/init is not the right file to look at, ..."  So, maybe the full answer is to do ps -p1 or look at /proc/1 to identify the program to query for.  (And, of course, use readlink, if appropriate.) – Scott Apr 14 '15 at 17:12
  • @Scott Yes, although I think in practice looking at /sbin/init should get you the right answer for most rpm and dpkg-based distributions, and others might need their own special-casing anyway. I'm in favor of not engineering in unnecessarily complexity just for theory. (I'll change my mind if you have a good example distro, though!) – mattdm Apr 14 '15 at 18:51
  • @mattdm Well, I was just responding to your last paragraph regarding init=/something/else. – Scott Apr 14 '15 at 18:52

From a program, you can also use the defined APIs for that. Systemd comes with libsystemd, which can check whether it can successfully connect to the running systemd instance.

  • That's a bit chicken-and-egg. That library won't exist on a system without systemd components at least present. You'd have to be using something like autoconf that can check for the existence of the library first. – Warren Young Apr 14 '15 at 18:27
  • The library would exist because the program requires it. This has been a huge controversy in Debian, but in the end it appears most people have accepted that libsystemd is going to be present on sysv systems as well, precisely to allow programs to find out whether systemd is active or not. – Simon Richter Apr 14 '15 at 18:29
  • You're not going to find it on a CentOS 5 or FreeBSD box. I, too, look forward to a world maybe 5 years hence where people have stopped trying to push back the tide, but today, you absolutely cannot count on being able to blindly link against libsystemd. – Warren Young Apr 14 '15 at 18:53
  • Well, if it's not available at build time, then just assume that the platform doesn't have systemd. Given the attitude of the developers, it is unlikely that systemd will ever be available for anything but Linux. – Simon Richter Apr 15 '15 at 5:09

Not the answer you're looking for? Browse other questions tagged or ask your own question.