这可能与检测操作系统有更多关系,但我特别需要系统上当前使用的 init 系统。
Fedora 15 和 Ubuntu 现在使用 systemd,Ubuntu 过去使用 Upstart(一直默认到 15.04),而其他版本则使用 System V 的变体。
我正在编写一个应用程序作为跨平台守护程序。初始化脚本是根据配置时传入的参数动态生成的。
我想做的只是为他们正在使用的特定初始化系统生成脚本。这样,安装脚本可以在没有参数的情况下以 root 身份合理运行,并且可以自动“安装”守护进程。
这就是我想出的:
- 在 /bin 中搜索 systemd、upstart 等
- 将 /proc/1/comm 与 systemd、upstart 等进行比较
- 询问用户
执行此操作的最佳跨/平台方式是什么?
有点相关,我可以依赖 bash 来支持大多数 *nix 还是依赖于发行版/操作系统?
目标平台:
- 苹果系统
- Linux(所有发行版)
- BSD(所有版本)
- Solaris、Minix 和其他 *nix
答案1
我自己也遇到了这个问题,并决定做一些测试。我完全同意应该为每个发行版单独打包的答案,但有时存在实际问题(尤其是人力)。
因此,对于那些想要“自动检测”的人,这就是我发现的在一组有限的发行版上(更多内容见下文):
你可以从以下方面辨别暴发户:
[[ `/sbin/init --version` =~ upstart ]] && echo yes || echo no
您可以通过以下方式告诉 systemd:
[[ `systemctl` =~ -\.mount ]] && echo yes || echo no
您可以通过以下方式告诉 sys-v init:
[[ -f /etc/init.d/cron && ! -h /etc/init.d/cron ]] && echo yes
这是我使用以下命令行进行的实验:
if [[ `/sbin/init --version` =~ upstart ]]; then echo using upstart;
elif [[ `systemctl` =~ -\.mount ]]; then echo using systemd;
elif [[ -f /etc/init.d/cron && ! -h /etc/init.d/cron ]]; then echo using sysv-init;
else echo cannot tell; fi
在 ec2 实例上(我包括 us-east AMI id):
- ArchLinux:使用 systemd(自2012.10.06)
- CentOS6.4 ami-52009e3b:使用upstart
- CentOS7 ami-96a818fe:使用 systemd
- Debian 6 ami-80e915e9:使用 sysv-init
- Debian 7.5 ami-2c886c44:使用 sysv-init
- Debian 7.6 GCE 容器虚拟机:使用 sysv-init
- RHEL 6.5 ami-8d756fe4:使用新贵
- SLES 11 ami-e8084981:使用 sysv-init
- Ubuntu 10.04 ami-6b350a02:使用 upstart
- Ubuntu 12.04 ami-b08b6cd8:使用 upstart
- Ubuntu 14.04 ami-a427efcc:使用 upstart
- Ubuntu 14.10 及更早版本:使用 systemd
- AWS linux 2014.3.2 ami-7c807d14:使用新贵
- Fedora 19 ami-f525389c:使用 systemd
- Fedora 20 ami-21362b48:使用 systemd
需要明确的是:我并不是说这是万无一失的!,几乎可以肯定不是。另请注意,为了方便起见,我使用 bash 正则表达式匹配,但并非所有地方都可用。以上对我现在来说已经足够了。但是,如果您发现某个发行版出现故障,请告诉我,如果有 EC2 AMI 重现该问题,我将尝试修复它...
答案2
对于第二个问题,答案是不你应该看看可移植 shell 编程的资源。
至于第一部分——首先,你一定要小心。我会说进行多项测试以确保- 因为事实上有人确实有systemd(例如)已安装,并不意味着它实际上被用作默认值init
。此外,查看/proc/1/comm
可能会产生误导,因为各种 init 程序的某些安装可以自动创建/sbin/init
符号链接硬链接,甚至是其主程序的重命名版本。
也许最有用的事情可能是查看 init 脚本类型 - 因为这些是您实际要创建的内容,无论运行它们的是什么。
顺便提一下,你也可以看看开放式RC其目的是提供一种兼容 Linux 和 BSD 系统的 init 脚本结构。
答案3
使用流程
查看几个ps
可以检测systemd
&的各种版本的命令的输出upstart
,可以像这样制作:
暴发户
$ ps -eaf|grep '[u]pstart'
root 492 1 0 Jan02 ? 00:00:00 upstart-udev-bridge --daemon
root 1027 1 0 Jan02 ? 00:00:00 upstart-socket-bridge --daemon
系统
$ ps -eaf|grep '[s]ystemd'
root 1 0 0 07:27 ? 00:00:03 /usr/lib/systemd/systemd --switched-root --system --deserialize 20
root 343 1 0 07:28 ? 00:00:03 /usr/lib/systemd/systemd-journald
root 367 1 0 07:28 ? 00:00:00 /usr/lib/systemd/systemd-udevd
root 607 1 0 07:28 ? 00:00:00 /usr/lib/systemd/systemd-logind
dbus 615 1 0 07:28 ? 00:00:13 /bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation
注意 PID #1 的进程名称也可能有助于了解正在使用哪个 init 系统。在 Fedora 19 上(使用systemd
,例如:
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 07:27 ? 00:00:03 /usr/lib/systemd/systemd --switched-root --system --deserialize 20
请注意,事实并非如此init
。在带有 Upstart 的 Ubuntu 上它仍然是/sbin/init
.
$ ps -efa|grep init
root 1 0 0 Jan02 ? 00:00:03 /sbin/init
笔记:但使用它时要小心一点。没有任何一成不变的东西表明特定的 init 系统正在给定的发行版上使用有作为systemd
PID #1。
通用的
$ (ps -eo "ppid,args" 2>/dev/null || echo "ps call error") \
| awk 'NR==1 || $1==1' | less
PPID COMMAND
1 /lib/systemd/systemd-journald
1 /lib/systemd/systemd-udevd
1 /lib/systemd/systemd-timesyncd
查看 ppid 1 的进程(init 进程的子进程)。 (某些)子进程名称可能指向正在使用的 init 系统。
文件系统
如果您询问init
可执行文件,您也可以从中获取一些信息。简单地解析--version
输出。例如:
暴发户
$ sudo /sbin/init --version
init (upstart 1.5)
Copyright (C) 2012 Scott James Remnant, Canonical Ltd.
This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE.
系统
$ type init
init is /usr/sbin/init
笔记:事实上,它init
不在标准位置,这有点暗示/说明。它始终位于/sbin/init
sysvinit 系统中。
系统维尼特
$ type init
init is /sbin/init
还有这个:
$ sudo init --version
init: invalid option -- -
Usage: init 0123456SsQqAaBbCcUu
结论
因此,似乎没有任何一种方法可以做到这一点,但您可以制定一套检查,以相当高的置信度查明您正在使用哪个初始化系统。
答案4
有时它就像使用一样简单ls
:
$ ls -l /sbin/init
lrwxrwxrwx 1 root root 20 juin 25 12:04 /sbin/init -> /lib/systemd/systemd
我想如果/sbin/init
不是符号链接,您将不得不进一步检查其他答案中的以下建议。