有没有一种简单的方法可以找出正在使用哪个 initsystem(例如最近的系统Debian wheezy
或Fedora
系统)?我知道它Fedora 21
使用systemd
initsystem 但那是因为我读过它并且因为所有相关脚本/符号链接都存储在/etc/systemd/
.但是,我不确定例如Debian squeeze
或CentOS 6 or 7
等等。
存在哪些技术可以验证此类 initsystem?
答案1
init 进程始终分配 PID 1。/proc
文件系统提供了一种在给定 PID 的情况下获取可执行文件路径的方法。
换句话说:
nathan@nathan-desktop:~$ sudo stat /proc/1/exe
File: '/proc/1/exe' -> '/sbin/upstart'
正如你所看到的,我的 Ubuntu 14.10 机器上的 init 进程是 Upstart。 Ubuntu 15.04 使用 systemd,因此运行该命令会产生:
nathan@nathan-gnome:~$ sudo stat /proc/1/exe
File: '/proc/1/exe' -> '/lib/systemd/systemd'
如果您所在的系统给出了/sbin/init
结果,那么您将需要尝试统计该文件:
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’
您还可以执行它来了解更多信息:
[user@centos ~]$ /sbin/init --version
init (upstart 0.6.5)
Copyright (C) 2010 Canonical Ltd.
答案2
您可以浏览系统以查找指标。一种方法是检查三个目录是否存在:
/usr/lib/systemd
告诉您您正在使用基于 systemd 的系统。/usr/share/upstart
是一个很好的指标,表明您正在使用基于 Upstart 的系统。/etc/init.d
告诉您该盒子的历史记录中有 SysV init
问题是,这些都是启发式的,必须一起考虑,可能与其他数据一起考虑,而不是单独考虑某些指标。我现在看到的 Ubuntu 14.10 盒子包含所有三个目录。为什么?因为 Ubuntu 在该版本中刚刚从 Upstart 切换到了 systemd,但保留了 Upstart 和 SysV init 以实现向后兼容。
最后,我认为最好的答案是“经验”。您将看到您已登录到 CentOS 7 机器并知道它是 systemd。你如何学习这个?玩耍、RTFMing 等。以同样的方式获得所有经验。
我意识到这不是一个非常令人满意的答案,但这就是当市场碎片化并产生非标准设计时就会发生的情况。这就像问你如何知道是否ls
接受-C
、或--color
、或根本不进行颜色输出。同样,答案是“经验”。
答案3
这其实是一个相当困难的问题。主要困难之一是,人们最常想要执行此操作的地方是人们很可能正在安装或更改东西的地方。另一个是,两者之间存在微妙但非常重要的区别安装的系统管理工具集,当前正在运行的系统管理工具集, 和将在下次启动时运行的系统管理工具集。
当然,可以使用包管理器来确定安装的内容。但由于多个系统可以并排安装,因此情况变得复杂。
例如,在 Debian Linux 上,可以安装系统包,不过是单独安装的systemd-sysv使其成为活动系统的软件包。其目的是 systemd 和系统维尼特软件包可以同时安装。事实上,Debian Linux 群体已经在 Debian 8 中采取措施转向每个程序都具有不同的名称(/lib/sysvinit/init
、/lib/systemd/systemd
、/sbin/runit-init
、/sbin/minit
、/sbin/system-manager
等),正是因为这个原因,“非激活”软件包不会在 Debian 8 上发生冲突。姓名/sbin/init
。 /sbin/init
然后是一个符号链接,指向通过“激活包”配置为在下次启动时运行的任何一个。
确定现在正在运行的内容以及准备运行下一个程序只能通过一系列特定于工具集的测试来完成,这些测试具有不同程度的误报风险以及不同程度的文档。具体来说,要检查系统管理器现在正在运行什么,我们确实必须查看进程列表或系统管理器发布的各种 API。但这并非完全没有陷阱。
一般不入手
让我们从肯定会发生的事情开始不是工作。
/proc/1/exe
/sbin/init
当新贵或系统 5init
正在运行时,将指向相同的内容。在某些系统上,这也是/sbin/init
在 systemd 运行时。如前所述,Debian Linux 人群希望每个程序都具有不同的名称。但这是 Debian 特有的,远的来自通用,并且当程序被调用时
/sbin/init
(通过引导程序的 initramfs 阶段)并没有真正的帮助。只有 Felix von Leitner 的 minit 实际上被 Debian 8 打包,以自己的名字调用。- 控制 API 文件的存在
/dev/initctl
并非特定于 System 5init
。 systemd 有一个(非进程#1)systemd-initctl
服务器来提供此服务。约阿希姆·尼尔森的finit
也服务它。 (为了让事情变得更加有趣,在 Debian 上它现在位于/run/initctl
。参见https://superuser.com/a/888936/38062了解详情。) - systemd、upstart、System 5
rc
和 OpenRC 所有进程/etc/init.d/
,以便在前两者的情况下向后兼容。它的存在并不表明任何给定系统的存在。
检测系统5init
具有讽刺意味的是,正如所解释的https://unix.stackexchange.com/a/196197/5132, 单程至少在 Debian Linux 上检测系统 5 是否存在的条件init
是 是否存在/etc/inittab
。然而:
- 这是 Debian 打包诸如
/etc/inittab
. - 整个问题的一部分是,如果使用
/etc/inittab
系统 5,这个问题仍然存在init
在过去的任何时刻,因为卸载包并不会删除其配置文件。 (这对于 Debian 8 工作来说是一个相当大的问题,因为 Debian 7 中有几个软件包通过向 . 中添加条目来安装自己/etc/inittab
。) - 这是一个反向测试。
检测系统
要以“官方”方式检查 systemd 作为正在运行的系统管理器,需要检查/run/systemd/system
.这是 systemd 本身在启动时创建的目录,位于 中/run
,其他系统管理器不太可能创建。
但这仅仅只是不太可能。这张支票是已经坏了, 因为 没用的也创建这个目录。
其他非官方检查不起作用:
- systemd 通过 D-Bus 发布了完整的 RPC API,其中甚至包含版本名称和版本号;但:
/run/systemd/private
同样不能保证 的存在,并且同样会被无用的重复。
检测 nosh
在system-manager
开胃菜创建一个/run/system-manager
目录。但这也有同等 systemd 检查的弱点。
其他非首发者:
- nosh
system-manager
的设计不会在文件系统中创建管道或套接字,并且一开始就没有 RPC API。 - nosh
service-manager
通常在 处有一个 API 套接字/run/service-manager/control
,但可以运行 nosh服务其他系统管理器下的管理器;所以这并没有告诉人们什么系统管理器作为进程 #1 运行。无论如何,它本身不会设置该名称;无论调用它什么。 system-control version
由发出的 nosh 版本字符串systemctl version
(如果安装了 systemd 兼容性垫片)和initctl version
(如果安装了 upstart 兼容性垫片)仅表明工具集的存在,因为这些工具不会查询正在运行的系统。
检测暴发户
Upstart 自己initctl
通过 D-Bus 进行 API 调用,官方检查是检查是否可以运行initctl
以及其输出是否在某处包含字符串“upstart”。
但是,就像 systemd API 一样:
- 无法保证 API 明天就会可用或不会随意更改。
- 无法保证某些兼容性填充程序不存在或将来不会存在。
事实上,已经存在一种兼容性垫片。 nosh 有一个 upstart 兼容性包,为 upstart
initctl
、start
、stop
和status
命令提供垫片。幸运的是(尽管这是故意的),initctl
垫片并没有发出“暴发户”这个词。root ~ #initctl 版本 诺什版本1.14 根~#
答案4
您还可以在程序中使用为此定义的 API。 Systemd 附带了 libsystemd,它可以检查是否可以成功连接到正在运行的 systemd 实例。