例如,在我的系统(16.04)上,有文件/lib/systemd/system/network-manager.service
和。/etc/init.d/network-manager
我不明白这是如何(以及为什么)起作用的。我总是通过 重新启动网络管理器sudo service network-manager restart
。这不会弄乱 systemd 吗?它似乎仍然有效。
为什么要service --status-all
列出所有类型的服务?16.04 不应该使用 systemd 而不是 Upstart 吗?
请有人解释一下这种共存是如何运作的。
答案1
一次只能激活一个 init 系统。在 16.04 上,该 init 系统为 systemd。
许多软件包附带了多个 init 系统的文件,因此它们可以在不同的操作系统上使用多个 init 系统进行管理。在 Ubuntu 上,有时会安装多个 init 系统的脚本,即使它们不是同时使用的。
较新的 init 系统会尝试与较旧的 init 系统保持兼容性。具体来说,systemd 会尝试与 Upstart 和 SysV init 脚本保持兼容性。
就您提到的“init.d”脚本而言,这是一个“SysV”初始化脚本,而不是 Upstart 脚本。此外,“SysV”初始化脚本只有在符号链接到“/etc/rc5.d”之类的目录时才会在启动时启动。您会发现网络管理器才不是在那里安装一个符号链接。
要了解如何systemd
管理旧的“SysV”启动脚本,请参阅systemd 如何使用 /etc/init.d 脚本?。
现在,回答为什么使用“service network-manager restart”重新启动网络管理器有效。该service
命令可与 Upstart 脚本和 SysV init 脚本一起使用,首选前者。网络管理器在 16.04 上也安装了一个 Upstart 脚本/etc/init/network-manager.conf
。
如果您查看 的输出sudo strace service network-manager restart
,您可以了解发生了什么。首先,输出显示 正在systemctl
被调用,表明该命令正在重定向到 systemd。首先,打开 后不久/usr/bin/service
,您可以看到它开始将文件作为 shell 脚本读取:
open("/usr/sbin/service", O_RDONLY) = 3
...
read(10, "#!/bin/sh\n\n#####################"..., 8192) = 8192
现在我们知道这service
是一个 shell 脚本,我们可以查看它的源代码。在源代码中,我们发现已is_systemd
检测并设置。对于 systemd 的情况,您可以看到命令被重写为systemctl restart network-manager
。
因此,虽然这三个 init 系统共存且具有一定的兼容性,但存在着层层复杂性。为了最大限度地降低未来发生的复杂性,最好使用 systemd 单元文件和工具systemctl
来管理服务。