systemd控制的服务如何区分关机和重启?

5

我有一个在RHEL7上由systemd启动的Linux进程。当该进程停止时,我需要知道它是因为系统关闭或重新启动而停止的,并且我需要能够区分这两种情况。

以前,在RHEL6 init下,我可以通过查看用于调用我的init脚本的路径名来完成此操作,并相应地向进程发送不同的信号,例如:

case "$0" in 
    *rc0\.d*|*rc1\.d*)     #shutdown
    sig=USR1
    ;;
    *rc6\.d*)              #reboot
    sig=USR2
    ;;
    *)
    sig=TERM
    ;;
esac

这在systemd中无法正常工作...虽然我的初始化脚本在正确的时间被调用,但$0始终相同(/etc/init.d/scriptname)。

在systemd下有没有某种方式可以知道您是因为系统关闭或重新启动而被调用?我很乐意摆脱初始化脚本并将其配置为systemd目标,但是从文档中我找不到实现我想要的方式。


你可以尝试使用 systemctl is-active reboot.targetsystemctl is-active shutdown.target - CameronNemo
顺便提一下,在没有systemd之前,找出问题的典型方法是调用“runlevel”并查看当前打印的运行级别(第二个字母/数字)。这相当于您的rcN测试,只是更加简洁。 - TvE
1个回答

3
CameronNemo的评论是正确的。特殊的systemd目标在“man systemd.special”或http://linuxmanpages.net/manpages/fedora14/man7/systemd.special.7.html中描述,重启目标在重新启动时处于活动状态。然而,关机目标在任何形式的系统终止(无论是重启还是停机)时都处于活动状态,因此它不能帮助区分。有关其他感兴趣的目标,请参见“man telinit”。我已经成功地使用了以下类型的代码:
/usr/bin/systemctl list-jobs | egrep -q 'shutdown.target.*start' && echo "shutting down" || echo "not shutting down"
/usr/bin/systemctl list-jobs | egrep -q 'reboot.target.*start' && echo "-> rebooting" || echo "-> not rebooting"
/usr/bin/systemctl list-jobs | egrep -q 'halt.target.*start' && echo "-> halting" || echo "-> not halting"
/usr/bin/systemctl list-jobs | egrep -q 'poweroff.target.*start' && echo "-> powering down" || echo "-> not powering down"

当关闭系统时,它总是会显示“正在关闭”,然后根据重启或关机也会显示“重新启动”或“正在关闭”。使用/sbin/halt将导致“停止运行”。当我尝试使用shutdown -h now时,它会转换为关机,但这可能取决于虚拟环境与物理环境。我已经在EC2 us-east上使用Fedora 20(ami-21362b48)和CentOS7(ami-96a818fe)进行了测试。如果您遇到此操作不起作用的情况,请留下评论,我会尝试修复!

1
原来 systemctl is-active ... 不可靠,因为当另一个关机单元运行时,reboot.target 可能处于等待状态。我现在正在使用 /usr/bin/systemctl list-jobs | egrep -q 'reboot.target.*start' && echo "rebooting" || echo "not rebooting"。一旦我有更多的清晰度,我会更新答案... - TvE
这是唯一对我有效的解决方案,谢谢。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接