如何使用 systemd 通知

Yve*_*ves 10 notification systemd

我正在学习如何使用 systemd 通知。我认为这是一种机制,它允许一个进程向另一个进程发送通知。

因此,我尝试使用命令发出通知systemd-notify --ready --status="hello"。然后我得到一个错误:No status data could be sent: $NOTIFY_SOCKET was not set。似乎它需要一个监听器,就像套接字一样。但我不知道如何让侦听器接收此通知。

另外,我知道 systemd 的服务有一些不同的类型,其中之一是notify. 医生说,Type=notify: identical to Type=simple, but with the stipulation that the daemon will send a signal to systemd when it is ready.。所以貌似notify类型的服务也可以发送通知,但是我也不知道怎么用。

fil*_*den 12

systemd-notify工具专门供作为 systemd 服务运行的 shell 使用Type=notify

如果您使用 设置服务Type=notify,systemd 将自动设置一个返回给 systemd 的通信套接字,并将其路径导出到$NOTIFY_SOCKET.

它还将侦听该套接字中的特殊消息,例如服务是否准备就绪(在这种情况下,systemd 会将其转换为 status started,因为初始化已完成)以及服务的自报告状态,这也会被报告在输出中systemctl status mytest.service(假设有一个名为 的服务mytest。)

您可以阅读手册页以systemd-notify了解所有详细信息,即使其中有很多复杂性……也许最后的示例有助于说明它的工作原理。


让我们使用该示例进行动手实验!

在系统中的某处创建一个如下所示的脚本,例如/usr/local/bin/mytest.sh

#!/bin/bash

mkfifo /tmp/waldo
sleep 10
systemd-notify --ready --status="Waiting for data…"

while : ; do
        read a < /tmp/waldo
        systemd-notify --status="Processing $a"

        # Do something with $a …
        sleep 10

        systemd-notify --status="Waiting for data…"
done
Run Code Online (Sandbox Code Playgroud)

我添加了一些sleep 10s 以便您在观看systemctl status mytest.service输出时可以看到发生了什么。

使脚本可执行:

$ sudo chmod +x /usr/local/bin/mytest.sh
Run Code Online (Sandbox Code Playgroud)

然后创建/etc/systemd/system/mytest.service,内容:

[Unit]
Description=My Test

[Service]
Type=notify
ExecStart=/usr/local/bin/mytest.sh

[Install]
WantedBy=multi-user.target
Run Code Online (Sandbox Code Playgroud)

然后重新加载 systemd(以便它了解该单元)并启动它:

$ sudo systemctl daemon-reload
$ sudo systemctl start mytest.service
Run Code Online (Sandbox Code Playgroud)

然后观察状态输出,每隔一段时间:

$ systemctl status mytest.service
Run Code Online (Sandbox Code Playgroud)

您会starting在前 10 秒看到它,之后它将是started,其状态将是“正在等待数据...”。

现在将一些数据写入 FIFO(您需要使用tee它以 root 身份运行它):

$ echo somedata | sudo tee /tmp/waldo
Run Code Online (Sandbox Code Playgroud)

并观察状态:

$ systemctl status mytest.service
Run Code Online (Sandbox Code Playgroud)

它将显示服务状态为“正在处理一些数据”10 秒,然后返回“等待数据...”。

如果您要用 C 或其他支持 systemd 绑定的语言编写此代码,您将sd_notify()为此目的使用该函数。如果您熟悉 C,则可能需要查看sd_notify(3)手册页。

  • @yves 不,`fifo` 与`systemd-notify` 无关。Filbranden 只是在此处将其用于示例脚本,以从另一个窗口以某种方式 _tickle_ 脚本。 (3认同)
  • 如果 systemd-notify 没有足够的权限来假装拥有调用进程的 PID(例如,由于 systemd 安全设置“RestrictNamespaces=yes”),则可能需要在服务单元中设置“NotifyAccess=all”。 (2认同)