次のような最小限の例を考えてみましょう。この問題、他のシェルスクリプトに加えて。
[Unit]
Description=Foo Service
After=network.target systemfoo.socket
Requires=systemfoo.socket
[Service]
Type=oneshot
ExecStart=/bin/bash /opt/foo/foo.sh
TimeoutStopSec=5
[Install]
WantedBy=multi-user.target
システム foo.socket
[Unit]
Description=Foo Socket
[email protected]
[Socket]
ListenStream=127.0.0.1:7780
Accept=Yes
[Install]
WantedBy=sockets.target
/opt/foo/foo.sh
#!/bin/bash
while true; do
logger -t FOO "Connection received: $REMOTE_ADDR $REMOTE_PORT"
done
つながると
nc 127.0.0.1 7780
スクリプトが正しく呼び出されました。ただし、CTRL-Cを使用して終了すると、nc
スクリプトは永久に実行されます。
ソケットを閉じるときにSIGTERMをスクリプトプロセスに送信するメカニズムはありますか(nc
終了時に実行すると仮定)?
答え1
いいえ、接続が閉じても、systemdはサービスを停止しません。
これが不可能な理由は、systemdがリッスンしているソケットへの新しい接続を受け入れると、そのソケットを接続処理を開始するサービスに渡し、接続への参照を保持しなくなるためです。
クライアントが接続を閉じたタイミングを検出するには、stdinが読み込みまたはポーリングしてソケットが閉じられていることを確認するように、サービス自体のソケットを確認する必要があります。