我正在使用 Centos 发行版。我在 etc 文件夹中有一个带有 K** 前缀的停止脚本
[linux_machine ~]$ ll /etc/rc0.d/
total 0
lrwxrwxrwx 1 root root 31 Apr 5 00:59 K01kill-agents -> /etc/init.d/kill-agents
还可以创建符号链接
echo "Providing necessary permissions to stop script"
chmod +x /etc/init.d/kill-agents
# on shutdown
ln -s /etc/init.d/kill-agents /etc/rc0.d/K01kill-agents
我是否需要执行一些命令来通知 Fedora?我尝试在停止脚本中放入 echo 语句,但在系统日志中看不到它们。
此外,这将在实例终止之前首先触发还是在 /etc/systemd 服务终止后触发。
编辑操作系统:Centos 8
答案1
首先,考虑到 SysV init,K
脚本rc0.d
没有什么意义。关机时,您不需要出口运行级别 0(即“poweroff”运行级别);你进入运行级别 0,因此开始中的服务rc0.d
,而不是停止它们。
唯一会被终止的服务是你的以前的运行级别,通常为2或5(您可以使用runlevel
命令来检查运行级别),即shutdown意味着rc5.d/K*
后面跟着rc0.d/S*
。
但是你的 CentOS 版本不使用 SysV init 系统;它使用 systemd,它根本不像 SysV init 那样处理 /etc/rc*.d 链接。相反,它尽最大努力将 SysV init 脚本转换为 systemd 单元,kill-agents.service
从 /etc/init.d 生成一个单元,链接rc*.d
仅用作依赖项提示. (但是,依赖项的主要来源是 init.d 脚本内的 LSB 标头 – systemd 不关注链接顺序。)
自动 SysV 转换不会查看K*
处的链接,只会查看 处的链接S*
,因为关闭是自动的——systemd 内置了服务状态跟踪,并且只会“停止”那些已开始。出于同样的原因,它也不会查看“关闭”运行级别rc0.d
或中的任何链接rc6.d
,从而使您的链接被双重忽略。
您应该为您的任务编写一个本机的 systemd 单元。(最好,“代理”本身应该是 systemd 服务,然后可以在正确的时间点停止。)请参阅Fedora 文档这样做。
如果无法将“代理”作为常规服务进行管理,并且您确实需要一个在关机时需要执行某些操作的“简单命令”脚本,则服务定义将以如下方式开始:
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/bin/true
ExecStop=/usr/local/bin/mytask.sh
也就是说,它会在启动时“启动”(不执行任何操作)并保持“启动”状态直到关闭;此时,systemd 将自动停止它并触发 ExecStop 操作。
(其余的,包括[Install]
,与正常的“启动时启动”服务相同,作为 multi-user.target 或类似程序的一部分启动。)
也可以创建一个看起来更简单的“关闭”服务,而不使用 RemainOnExit=,它挂接到 shutdown.target 而不是 multi-user.target,但如果这样做,很难根据正在运行的各种服务对其进行排序停止关机时。
此外,这将在实例终止之前首先触发还是在 /etc/systemd 服务终止后触发。
所有 systemd 服务都会在其依赖项允许的情况下尽早停止,如果可能的话会并行停止。(例如,如果服务被排序Before=foo.service
,那么它将在 foo.service 之前启动,并将停止后foo.service 已停止完成。)当两个服务之间没有顺序或依赖关系时,它们可以并行启动和停止。
因此,如果你有一个带有 ExecStop 的“一次性”服务(如上例所示),并且希望它在服务 XYZ 停止之前执行“停止”操作,则需要定义对面的启动依赖项,即After=XYZ.service
。(也就是说,假装该操作是在启动时执行的。)
对于 SysV 脚本,systemd 从 init.d 脚本 LSB 头读取依赖项,但不关注S
或K
链接顺序。