次のようなテストスイートターゲットを含むメイクファイルがあります。
rcheck:
foo
これは、stdoutのfoo
コマンドからの出力を示し、通常どおりmakeによって処理されるfoo
からの終了コードを返します。
このターゲットにsomethingを追加して、既存の動作に影響を与えずにfoo
の出力を解析したい-つまり、
foo
のstdout/stderrは、以前と同様にstdout/stderrに表示されます。foo
の終了コードが何であれです。foo
からのstdoutは、どういうわけか、2番目のコマンドbar
に渡される必要があります。 bar
の終了コードは重要ではなく、bar
は上記の1.に加えてstdoutまたはstderrに何も出力しないでください(ソリューションがbar
が1.自体を処理することを意味する場合を除く)ここで最も良い解決策は何ですか?
Fooからbarに渡されるデータのタイミングについて心配しておらず、クリーンなターゲットで処理する必要がある一時ファイルで問題がない場合は、次のようにします。
rcheck:
foo | tee sometempfile
-bar < sometempfile >/dev/null 2>/dev/null
一方、タイミングを重視する場合は、barにstdoutへの入力を繰り返して、次のようなことを試すことができます。
rcheck:
-(foo; echo $$? > sometempfile) | bar
exit $(cat sometempfile)
よりクリーンな方法があると確信していますが、上記が思い浮かびました。 (注、どちらもテストされていません)
pipefail
オプション(bash、ksh、およびzsh do)をサポートするシェルを使用している場合は、次のように実行できます。
rcheck:
set -o pipefail; foo | tee /dev/stderr | { bar >/dev/null 2>&1; true; }
私のkshマンページには、そのオプションが次のように記載されています。
pipefail パイプラインのすべてのコンポーネントが完了するまでパイプラインは完了しません 。戻り値は最後のゼロ以外の値です コマンド失敗するか、失敗したコマンドがない場合はゼロ。
デフォルトの動作とは対照的に:
パイプラインの終了ステータスは、最後のコマンドの終了ステータスです pipefailオプションが有効になっていない場合。