シェルパイプからプロセス信号「終了」メッセージ出力をキャプチャします。

シェルパイプからプロセス信号「終了」メッセージ出力をキャプチャします。

プロセスがシグナルを介して終了すると、使用されているシグナルに似ているTerminatedか、それに応じて異なるメッセージが出力されます。Killedこのメッセージをキャプチャできますか?

次のパイプラインを例にします。

while true; do timeout 2 sleep 5; done

何も出力せずにsleep2秒ごとに終了します。 1つを追加cat:

while true; do timeout 2 sleep 5 | cat; done

Terminated2秒ごとに出力されますが表示されませんcat。に置き換えると、catファイルtee somefileはまだ空です。

2>&1コマンドラインのさまざまな場所からリダイレクトしようとしましたが、出力をTerminatedファイルにインポートできませんでした。

libcループではなくターミナルシェルに接続されたコマンドを介して出力されるようです。

Terminated同様の出力をパイプに入れることはできますか?

sleep(最終的にはtheをaに、curltheをスクリプトに置き換え、出力とメッセージを処理したいと思います。)catawkcurlTerminated

ベストアンサー1

分析する

はい、これはシェルが印刷するものですTerminated。解雇されたのでtimeout 2 sleep 5 | cat見ると。そして私Terminatedcatする意味はですcat

これの説明は次のとおりです。私の他の答えは次のとおりです。timeoutあなたの場合は、SIGTERMをプロセスグループ全体に送信してください。sleep そして cat

プロセスグループtimeoutも含まれます。独自の信号で終了しないようです。これがtimeout単独でシェルを印刷しない理由です。ただし、これはSIGKILLをキャプチャしたり無視したりすることができないため、シェルでこれを見ることができます。 SIGKILLで殺すと、自分で死んでシェルが反応します。timeout 2 sleep 5Terminatedtimeout -s KILL 2 sleep 5Killedtimeoutsleep

だからそれがあなたが観察することがcat最も重要ですTerminated。これで、sleepに置き換えると合計curlが終了します。しかし、メッセージを印刷することはシェルであるため重要ではありません。本当にメッセージをキャプチャするには、パイプからキャプチャする必要があります。catawktimeoutcurlawkawk後ろにシェル。


解決策

本当にメッセージをキャプチャするには、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

おすすめ記事