本文译者是一位开源理念的坚定支持者,所以本文虽然不是软件,但是遵照开源的精神发布。
本文译者十分愿意与他人分享劳动成果,如果你对我的其他翻译作品或者技术文章有兴趣,可以在如下位置查看现有的作品集:
由于译者水平有限,因此不能保证译文内容准确无误。如果你发现了译文中的错误(哪怕是错别字也好),请来信指出,任何提高译文质量的建议我都将虚心接纳。
systemd-notify — 向 systemd 报告服务状态的变化
systemd-notify [OPTIONS...] [VARIABLE=VALUE...]
systemd-notify 可用于 在守护进程脚本中向 systemd 报告进程状态的变化。 可用于发送任意信息, 其中最重要的是 报告"启动已完成"的消息。
此工具基本上就是对
sd_notify()
的简单包装,
以便于在脚本中使用。详见
sd_notify(3) 手册。
注意,在报告状态更新的同时, 还可以传递一系列环境变量。
注意,在默认情况下(也就是调用此命令的服务单元含有 NotifyAccess=none
),
systemd 并不从此命令接受状态更新消息。
注意,服务单元的 sd_notify()
通知能够正常工作的前提,
是必须满足如下两个条件之一:
(1)在 PID=1 的进程处理通知消息时,发送该通知的进程依然在运行;
(2)发送该通知的进程是 systemd 派生的子进程(也就是匹配 NotifyAccess=main
或 NotifyAccess=exec
的进程)。
如果服务单元中的某个辅助进程在发送了 sd_notify()
通知之后就立即退出了,
那么 systemd 将有可能来不及将该通知关联到这个服务单元上。
在这种情况下,即使明确设置了 NotifyAccess=all
,
该通知也可能会被忽略掉。
systemd-notify 会首先尝试以调用进程的PID来调用 sd_notify()
(此操作仅在确实拥有足够权限的情况下才会成功),
如果失败,将会使用其自身的PID再次调用 sd_notify()
。
这种做法对于从 shell 脚本中调用 systemd-notify 命令非常有用,
特别是当服务的主进程是 shell 的时候(由于 NotifyAccess=all
的限制),
因为在这种情况下,
shell 进程(而不是 systemd-notify 进程)将成为消息的发送者。
能够识别的命令行选项如下:
--ready
¶向 systemd 报告"启动已完成"的消息。 这等价于 systemd-notify READY=1 。 详见 sd_notify(3) 手册。
--pid=
¶向 systemd 报告主守护进程的 PID 。 如果 PID 参数被省略, 将使用调用 systemd-notify 的进程的 PID 。 这等价于 systemd-notify MAINPID=$PID 。 详见 sd_notify(3) 手册。
--uid=
USER
¶向 systemd 报告此消息来自哪个用户,也就是使用指定的
USER
取代调用此命令的用户,作为此通知消息的发送者。
USER
既可以是一个UID数值也可以是一个用户名字符串。
此选项需要足够的权限才能操作进程的用户标识。
--status=
¶向 systemd 发送一个任意内容的字符串消息。 这等价于 systemd-notify STATUS=… 。 详见 sd_notify(3) 手册。
--booted
¶用于检查系统的 init 进程是否为 systemd ,
返回 0 表示系统的 init 进程是 systemd ,返回非零表示其他。
此选项并不发送任何消息,因此与其他选项没有任何关系。
详见
sd_booted(3) 手册。
另一种检查方法是
systemctl(1)
的 is-system-running 命令。
若返回 "offline
" 则表示
系统的 init 进程不是 systemd
-h
, --help
¶--version
¶例 1. 启动通知与状态更新
一个简单的守护进程脚本,在创建好通信管道之后, 向 systemd 报告"启动已完成"的消息。在运行时, 向 systemd 报告更多的状态消息:
#!/bin/bash mkfifo /tmp/waldo systemd-notify --ready --status="Waiting for data…" while : ; do read a < /tmp/waldo systemd-notify --status="Processing $a" # Do something with $a … systemd-notify --status="Waiting for data…" done