リモートでサービスを停止するのに問題があります。
シンプルなソケット/サービスペアがあります。
# /etc/systemd/system/foo.socket
[Unit]
Description=The socket
[Socket]
ListenStream=11111
# /etc/systemd/system/foo.service
[Unit]
Description=The service
[Service]
Type=simple
ExecStart=sleep infinity
その後はsystemctl start foo.socket
次のようになります。
foo.socket: active (listening)
foo.service: inactive (dead)
その後、他のシステムへの接続を確立すると、次のような結果がnetcat 10.10.1.16 11111
得られます。
foo.socket: active (running)
foo.service: active (running)
完璧!
SIGTERM
これで接続(to)を終了すると、netcat
次のようになります。
foo.socket: active (running)
foo.service: active (running)
しかし、私は次のように予想しました。
foo.socket: active (listening)
foo.service: inactive (dead)
TCP接続を使用してリモートでサービスを停止する方法は?
私は試した:
Accept=yes
そして[email protected]
- サービスを提供
PartOf=foo.socket
するRequires=foo.socket
StandardInput=socket
そして標準出力と標準エラー。
答え1
代わりに/bin/sleep infinity
別のものを実行したいと思います。
[Service]
Type=simple
ExecStart=foo
StandardInput=socket
次はどこですかfoo
?
#include <stdio.h>
int main(int, char**) {
char buf[256];
while(scanf("%255s",buf) > 0) {}
return 0;
}
#!/bin/sh
while read line; do
echo "$line"
done < "${1:-/dev/stdin}"
#!/usr/bin/python3
import sys
for line in sys.stdin:
pass
#!/usr/bin/perl
while (<>) {
if (eof()) { exit }
}
説明する:
サービスを使用すると、プロセスが終了Type=simple
するとすぐにサービスが停止しますExecStart
。したがって、接続を閉じてもアプリケーションを終了する必要があることがわからないため、サービスは停止されません。 SystemdはSIGTERMを送信せず、それも必要ありません。
ExecStart
代わりに、同じことを行う4つのプロセス(C、sh、python、perl)の実装を提供します。つまり、stdin が使用できなくなるまで stdin から読み込みます。接続が閉じられると、ストリームは終了します。これはstdinが終了することを意味します。したがって、EOFが得られるまでstdinを読み続け、終了します。プロセスが終了すると、サービスは停止します。
組み込み機能
上記のスクリプトのいずれかをデプロイしたくない場合は、stdinを受け取り、EOFで終了する組み込みツールの1つを使用してください。副作用は彼らが実際に何かをするかもしれないということです。最初に考えられるのはですgrep -
。EXIT_FAILURE
一致するものがない場合は返されるので、-
接続が閉じられるたびにサービスが失敗しないようにプレフィックスを付けます。
[Service]
Type=simple
ExecStart=-/bin/grep -
StandardInput=socket
このプロセスを活用するのが楽しいと思う場合は、接続を介して役に立つことができます。私が考えることができる2番目のプログラムはpython3
。これで、通訳者全体がアイドル状態で座って、あなたのために何かをすることができます。サンドボックスを追加していませんが、systemdが機能していると危険ですDynamicUser=
。
[Service]
Type=simple
ExecStart=/usr/bin/python3
StandardInput=socket
DynamicUser=yes
クライアント側で接続が確立されていることを確認するには、cat
まず次の定型句テキストを作成することをお勧めします。
echo "established" > /usr/local/etc/simple/start_text
次に、systemdにそのテキストをキャットし、stdinを指定するように指示します。
[Service]
Type=simple
ExecStart=-cat /usr/local/etc/simple/start_text -
StandardInput=socket
netcat
接続が確立されると、クライアントは印刷物を受け取ります。
Accept=yes
andを使用する必要があることにも注目する価値があります[email protected]
。それ以外の場合、systemdはアプリケーションが着信接続を受け入れることを期待しますが、ここではそうではありません。