Systemd notifyの使い方を学んでいます。プロセスが別のプロセスに通知を送信できるメカニズムのようなものだと思います。
そこで、systemd-notify --ready --status="hello"
。次に、エラーが発生しました:No status data could be sent: $NOTIFY_SOCKET was not set
。ソケットのようにリスナーが必要なようです。しかし、この通知を受け取るようにリスナーを作成する方法がわかりません。
また、systemdのサービスにはいくつかの異なるタイプがあることを知っています。そのうちの1つは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のサービスでも通知を送信できるようですが、使い方もわかりません。
_systemd-notify
_ツールは、_Type=notify
_を使用してsystemdサービスとして実行されるシェルによって使用されることを特に意図しています。
_Type=notify
_を使用してサービスをセットアップすると、systemdは自動的に通信ソケットをsystemdにセットアップし、そのパスを_$NOTIFY_SOCKET
_でサービスにエクスポートします。
また、サービスの準備ができているかどうか(初期化が完了しているため、systemdがステータス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
_
_sleep 10
_の出力を見て、何が起こっているかを確認できるように、いくつかの_systemctl status mytest.service
_ sを追加しました。
スクリプトを実行可能にします。
_$ Sudo chmod +x /usr/local/bin/mytest.sh
_
次に、内容を含む_/etc/systemd/system/mytest.service
_を作成します。
_[Unit]
Description=My Test
[Service]
Type=notify
ExecStart=/usr/local/bin/mytest.sh
[Install]
WantedBy=multi-user.target
_
次にsystemdをリロードし(ユニットについて学習するため)、それを起動します。
_$ Sudo systemctl daemon-reload
$ Sudo systemctl start mytest.service
_
次に、ステータス出力を時々監視します。
_$ systemctl status mytest.service
_
最初の10秒間はstarting
であることがわかります。その後、started
になり、ステータスは「データを待機しています...」になります。
FIFOにデータを書き込みます(ルートとして実行するにはtee
を使用する必要があります):
_$ echo somedata | Sudo tee /tmp/waldo
_
そしてステータスを見てください:
_$ systemctl status mytest.service
_
サービスのステータスが「データの処理中」として10秒間表示され、「データの待機中...」に戻ります。
このコードをCまたはsystemdバインディングをサポートする別の言語で記述する場合は、この目的でsd_notify()
関数を使用します。 Cに精通している場合は、 sd_notify(3) のマニュアルページをご覧ください。
完全な答えではありませんが、「netcat」を使用してこれまでに行きました
A)1つのターミナルセッションで、次の操作を行います。
export NOTIFY_SOCKET=/tmp/test.sock
nc -l -U -u /tmp/test.sock
B)別のターミナルセッションを開き、次の操作を行います。
export NOTIFY_SOCKET=/tmp/test.sock
systemd-notify --read --status="hello"`
これは機能しますが、netcat
側ではnc: connect: Invalid argument
。私はそれを回避する方法を知りません。
メッセージ形式sd_notifyを学ぶには、これを試すことができます:
ターミナル1:
$ socat unix-recv:/tmp/test.sock -
ターミナル2:
$ NOTIFY_SOCKET=/tmp/test.sock systemd-notify --ready --status="hello"
ターミナル1に結果が表示されます。
READY=1
STATUS=hello