だから斧を持ってデスクトップを破壊する前にここに尋ねてみましょう:-)
Commander.serviceというソケットアクティベーションサービスがあります。単純性のため、このサービスには文字列または文字だけをプッシュしたいと思います。
だからCommander.socketファイルがあります。
[Socket]
ListenFIFO=/run/commander.sk
[Install]
WantedBy=sockets.target
その後、Commander.serviceファイルがあります。
[Unit]
Description=A service reading commands from the given socket
[Service]
ExecStart=/usr/bin/perl /root/commander.pl
StandardInput=socket
User=root
Group=root
Restart=no
[Install]
WantedBy=multi-user.target
これで、標準入力を介してこれらの文字列または文字を受け取るために実行するスクリプトが必要です。
このスクリプトのコードは次のとおりです。
#!/usr/bin/env perl
my $in = *STDIN;
my $out = *STDOUT;
$out->print("My printing reaches the outside world\n");
while($_ = <$in>) {
$out->print("Received: ");
$out->print($_);
$out->print("\n");
if($_ == "1") {
$out->print("I should run the command associated with 1 ;-) \n");
} elsif($_ == "2") {
$out->print("I should run the command associated with 2 ;-) \n");
} else {
$out->print("Oh! did someone just try to trick me?\n");
}
}
$out->print("And I'm gone!\n");
通常、標準出力はジャーナルと通信する必要があり、そこの印刷もジャーナルに渡されることを願っています。
今問題は次のとおりです。
私がするとき:
echo "1" > /run/commander.sk
Commander.serviceが有効になっていますが、ログではログのみを表示できます。
Dez 22 03:18:25 phantom systemd[1]: Started A service reading commands from the given socket.
Dez 22 03:31:32 phantom systemd[1]: Stopping A service reading commands from the given socket...
Dez 22 03:31:32 phantom systemd[1]: Stopped A service reading commands from the given socket.
Dez 22 03:31:41 phantom systemd[1]: Started A service reading commands from the given socket.
これは、印刷が外部の世界に到達しないことを意味します。何かを更新して設定を再インストールすると、手動で停止します。
コンソールからcommand.plスクリプトを呼び出すと、期待どおりに機能することがわかります。 stinで読み、stdoutと話します。
私はまた、それがどのように機能するべきかについてより多くの誤解があった数時間前に印刷物が日誌に到着したことを知っています。
私が知る限り、私は標準出力が行く場所を変えることができる何もしません。この期間中に私がした最も重要なことは、私にとって最も必要なものを特定することでした。
StandardInput=socket
ラインはソケットを標準入力として受け取ります。
私は今2日連続でこの問題と戦っているので、ずっと髪を抜いて家具に対して積極的に変わり始めてください^^ どんな助けでもとても、とても感謝します:-)
とにかく、現在のコードはatm onlineです。 https://github.com/JhonnyJason/pull-deploy-commander-service
修正する 使用するとき
StandardInput=socket
StandardOutput=journal
サービススクリプトは永久に活発に実行されますが、ログには何も出力しません。
これらの2行をコメントアウトすると、stdinから何も読み取られませんが、少なくともログにはstdoutがあります。サービスは、systemdが再起動を拒否するまでアクティブになります。
以下は、コメントアウトされた@04:05:58実行のログです。 @04:25:07 次の行で実行してください。
Dez 22 04:05:58 phantom systemd[1]: Started A service reading commands from the given socket.
Dez 22 04:05:58 phantom perl[4687]: My printing reaches the outside world
Dez 22 04:05:58 phantom perl[4687]: And I'm gone!
Dez 22 04:05:58 phantom systemd[1]: Started A service reading commands from the given socket.
Dez 22 04:05:58 phantom perl[4689]: My printing reaches the outside world
Dez 22 04:05:58 phantom perl[4689]: And I'm gone!
Dez 22 04:05:58 phantom systemd[1]: Started A service reading commands from the given socket.
Dez 22 04:05:58 phantom perl[4691]: My printing reaches the outside world
Dez 22 04:05:58 phantom perl[4691]: And I'm gone!
Dez 22 04:05:58 phantom systemd[1]: Started A service reading commands from the given socket.
Dez 22 04:05:58 phantom perl[4693]: My printing reaches the outside world
Dez 22 04:05:58 phantom perl[4693]: And I'm gone!
Dez 22 04:05:58 phantom systemd[1]: Started A service reading commands from the given socket.
Dez 22 04:05:58 phantom perl[4695]: My printing reaches the outside world
Dez 22 04:05:58 phantom perl[4695]: And I'm gone!
Dez 22 04:05:58 phantom systemd[1]: commander.service: Start request repeated too quickly.
Dez 22 04:05:58 phantom systemd[1]: Failed to start A service reading commands from the given socket.
Dez 22 04:05:58 phantom systemd[1]: commander.service: Unit entered failed state.
Dez 22 04:05:58 phantom systemd[1]: commander.service: Failed with result 'start-limit-hit'.
Dez 22 04:25:07 phantom systemd[1]: Started A service reading commands from the given socket.
答え1
だから私は
commander.socket
[...]を持っていて、それから[...]
を持っています。commander.service
...そしてあなたはPerlで書いています。
Perlが問題の原因です。 systemdとは何の関係もありません。これらはすべて実行中のデバイス設定には関係ありません。誰でも指定するStandardInput=socket
またはファイル記述子#3を使用するようにサービスを作成します。
サービスの標準入力はFIFOに接続され、標準出力とエラーはストリームソケット(/run/systemd/journal/stdout
、ログと通信)に接続されます。
標準入出力ファイル記述子は端末装置ではないため、PerlはI / Oをラインバッファリングまたは単位バッファリングしません。
標準出力が端末装置でない場合、装置バッファリング(「autoflush」)への明示的な遷移はありませんが、はい出力が発生したらすぐにどこか(ログなど)を見たいのは、Perlでよく犯される間違いです。
したがって、stdoutを「hot」/「auto-refresh」にしてセルバッファリングを有効にします。
追加読書
- ブライアンD.ポイ」出力ファイルハンドルをフラッシュ/バッファ解除する方法は?なぜ私はこれをするべきですか?」。Perl 5ドキュメント。 perl.org.
$|
。 「パーバル」。 Perl 5ドキュメント。 perl.org.- マーク・ジェイソン・ドミナス(1998)。 」バッファリングのために苦労していますか?」。 パールマガジン。フローバーのホームページ。