web-dev-qa-db-ja.com

後でMakefileでコマンド終了コードをキャッチするにはどうすればよいですか?

次のようなテストスイートターゲットを含むメイクファイルがあります。

rcheck:
        foo

これは、stdoutのfooコマンドからの出力を示し、通常どおりmakeによって処理されるfooからの終了コードを返します。

このターゲットにsomethingを追加して、既存の動作に影響を与えずにfooの出力を解析したい-つまり、

  1. fooのstdout/stderrは、以前と同様にstdout/stderrに表示されます。
  2. makeに関する限り、rcheckターゲットの最終的な結果は、fooの終了コードが何であれです。
  3. fooからのstdoutは、どういうわけか、2番目のコマンドbarに渡される必要があります。 barの終了コードは重要ではなく、barは上記の1.に加えてstdoutまたはstderrに何も出力しないでください(ソリューションがbarが1.自体を処理することを意味する場合を除く)

ここで最も良い解決策は何ですか?

6
directhex

Fooからbarに渡されるデータのタイミングについて心配しておらず、クリーンなターゲットで処理する必要がある一時ファイルで問題がない場合は、次のようにします。

rcheck:
        foo | tee sometempfile
        -bar < sometempfile >/dev/null 2>/dev/null

一方、タイミングを重視する場合は、barにstdoutへの入力を繰り返して、次のようなことを試すことができます。

rcheck:
        -(foo; echo $$? > sometempfile) | bar
        exit $(cat sometempfile)

よりクリーンな方法があると確信していますが、上記が思い浮かびました。 (注、どちらもテストされていません)

2

pipefailオプション(bash、ksh、およびzsh do)をサポートするシェルを使用している場合は、次のように実行できます。

rcheck:
    set -o pipefail; foo | tee /dev/stderr | { bar >/dev/null 2>&1; true; }

私のkshマンページには、そのオプションが次のように記載されています。

 pipefail 
パイプラインのすべてのコンポーネントが完了するまでパイプラインは完了しません
。戻り値は最後のゼロ以外の値です
コマンド失敗するか、失敗したコマンドがない場合はゼロ。

デフォルトの動作とは対照的に:

パイプラインの終了ステータスは、最後のコマンドの終了ステータスです
 pipefailオプションが有効になっていない場合。
1
godlygeek