![如何区分 systemd 单元是由 apt-get 运行还是在引导期间运行?](https://linux22.com/image/65255/%E5%A6%82%E4%BD%95%E5%8C%BA%E5%88%86%20systemd%20%E5%8D%95%E5%85%83%E6%98%AF%E7%94%B1%20apt-get%20%E8%BF%90%E8%A1%8C%E8%BF%98%E6%98%AF%E5%9C%A8%E5%BC%95%E5%AF%BC%E6%9C%9F%E9%97%B4%E8%BF%90%E8%A1%8C%EF%BC%9F.png)
人们能否以某种方式区分,
- a) 守护进程在引导期间启动,或者,
- b) 通过 apt-get 安装或升级(重新)启动?
这可以从守护进程本身中区分出来吗?
这里的用例是让 systemd 运行的脚本Type=oneshot
仅在启动时运行。不在 apt-get 安装或升级期间。
答案1
编辑:请注意,我只谈论 PID 1,因为我不会英语,并且认为您想检查您的主要 init 进程。将其更改为您感兴趣的单位。我确信 systemd 会以某种方式为您吐出 PID。或者如果没有,ps ax |grep [commandname]
就会这样做。您可能还需要调整正常运行时间和进程运行时间之间的时间差,只需+3
在 bc 行中添加 a 或其他内容即可。/编辑
我没有使用 systemd,所以对此持保留态度。与初始化系统无关的方法是比较您感兴趣的进程的启动时间和系统正常运行时间。你可以通过ps -o etimes [PID]
.传统上,PID 1 是为 init 进程保留的,但我不知道 systemd 是否遵循它。检查ps 1
这是否确实是您感兴趣的过程,如果不是,请进行调整。您可以使用cat /proc/uptime |cut -d "." -f 1
.分隔符cut
是点,因为ps
也会删除小数。
将它们与 bc 或您最喜欢的方式进行比较。命令行示例可以是:
echo $(cut -d "." -f 1 /proc/uptime)"-"$(ps -o etimes [PID] |tail -n 1 |tr -d ' \t')|bc
如果进程在引导时启动,则预期输出为 0。您可以检查它是否与您的发现相符。对于 shell 脚本,我会通过 if/then 测试运行它,并接受可能 +-3 秒作为启动时间。至少一秒钟。否则,如果它们的正常运行时间相差一小部分,您偶尔可能会得到非零答案,这可能会导致难以调试的错误。
答案2
根据设计,systemd 将在启动时或更新期间通过在相同环境下运行相同命令等来启动和重新启动服务。因此,没有直接的方法可以知道服务是在启动时运行还是在更新后重新启动。作为管理员,您可以通过查看单元启动时间、日志等来推断这一点。
但是,您可以通过向服务单元添加特定逻辑来解决此问题,例如使用:
[Unit]
...
ConditionPathExists=!/run/service-was-started-before
[Service]
...
ExecStartPre=touch /run/service-was-started-before
...
或者您可以使用 systemd 计时器仅在启动时运行该命令(请参阅systemd.定时器(5))还是老好cron
。