プロセスがシグナルを介して終了すると、使用されているシグナルに似ているTerminated
か、それに応じて異なるメッセージが出力されます。Killed
このメッセージをキャプチャできますか?
次のパイプラインを例にします。
while true; do timeout 2 sleep 5; done
何も出力せずにsleep
2秒ごとに終了します。 1つを追加cat
:
while true; do timeout 2 sleep 5 | cat; done
Terminated
2秒ごとに出力されますが表示されませんcat
。に置き換えると、cat
ファイルtee somefile
はまだ空です。
2>&1
コマンドラインのさまざまな場所からリダイレクトしようとしましたが、出力をTerminated
ファイルにインポートできませんでした。
libc
ループではなくターミナルシェルに接続されたコマンドを介して出力されるようです。
Terminated
同様の出力をパイプに入れることはできますか?
sleep
(最終的にはtheをaに、curl
theをスクリプトに置き換え、出力とメッセージを処理したいと思います。)cat
awk
curl
Terminated
ベストアンサー1
分析する
はい、これはシェルが印刷するものですTerminated
。解雇されたのでtimeout 2 sleep 5 | cat
見ると。そして私Terminated
cat
する意味はですcat
。
これの説明は次のとおりです。私の他の答えは次のとおりです。。timeout
あなたの場合は、SIGTERMをプロセスグループ全体に送信してください。sleep
そして cat
。
プロセスグループtimeout
も含まれます。独自の信号で終了しないようです。これがtimeout
単独でシェルを印刷しない理由です。ただし、これはSIGKILLをキャプチャしたり無視したりすることができないため、シェルでこれを見ることができます。 SIGKILLで殺すと、自分で死んでシェルが反応します。timeout 2 sleep 5
Terminated
timeout -s KILL 2 sleep 5
Killed
timeout
sleep
だからそれがあなたが観察することがcat
最も重要ですTerminated
。これで、sleep
に置き換えると合計curl
が終了します。しかし、メッセージを印刷することはシェルであるため重要ではありません。本当にメッセージをキャプチャするには、パイプからキャプチャする必要があります。cat
awk
timeout
curl
awk
awk
後ろにシェル。
解決策
本当にメッセージをキャプチャするには、awk
メッセージを印刷するシェルの後にパイプを追加する必要があります。そして終了した「被害者」プロセスが必要であり、このプロセスがなければメッセージはありません。また、PIDと同じPGIDを持つプロセスグループで実行されるシェルが必要ですtimeout
。これはメカニズムにとって重要である(リンクされた回答を参照)。たとえば、awk
次のパイプラインではメッセージを正常に処理する必要があります。
bash -ic 'timeout 2 sleep 5 | cat' 2>&1 | awk '{print "This is the message: "$0}'
-i
それは重要です。それがなければ、timeout
私たちの貧しい非難者を殺すことはありませんcat
。厳密に言えば、これは対話型または非対話型のBashとは何の関係もありません。これには、ジョブ制御の有効化(対話型Bashではデフォルトで有効)または無効(非対話型Bashではデフォルトで有効)が含まれます。したがって、これも機能します。
bash -c 'set -m; timeout 2 sleep 5 | cat' 2>&1 | awk '{print "This is the message: "$0}'
よりエレガントなソリューション
欲しいものを行うより簡単な方法があります。最終的にスクリプトで実行したい場合は、スクリプトを解釈するシェルがそのコマンドに対して別々のプロセスグループを作成してはならないという事実を利用できます。非対話型スクリプトではtimeout … | awk
終了しませんawk
。
今あなたが必要とするのは、timeout -v
それが何をしているのかを聞くだけです。次の例は、非対話型スクリプトで実行するように設計されています。対話型Bashでテストするには可能ですが、まずジョブ制御(set +m
)を無効にする必要があります。スクリプトは次のとおりです。
#/bin/sh
timeout -v 2 sleep 5 2>&1 | awk '{print "This is the message: "$0}'
sleep
使用。 。 。交換curl
。検出しようとするのではなく、awk
探してください。timeout: sending signal TERM to command '…'
Terminated