後で使用するためにMakefileでコマンド終了コードをどのようにキャプチャしますか?

後で使用するためにMakefileでコマンド終了コードをどのようにキャプチャしますか?

次のテストスイートターゲットを含むmakefileがあります。

rcheck:
        foo

これはstdoutにコマンドの出力を表示し、正常にハンドルを作成するfoo終了コードを返します。foo

追加したいこの目標を達成するには、foo既存の動作に影響を与えずに出力を解析します。つまり:

  1. foostdout/stderr は、以前と同様に stdout/stderr に表示する必要があります。
  2. Makeに関する限り、rcheckの目標の最終結果はfoo終了コードです。
  3. stdout fromはfoo何らかの方法で2番目のコマンドに渡す必要がありますbarbar終了コードは重要ではありません。bar上記の1.以外はstdoutまたはstderrに出力しないでください(ソリューションがbar1.それ自体を処理することを意味しない限り)。

ここで最も独創的な解決策は何ですか?

答え1

データが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の両方をサポート)、次のことができます。

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

私のkshのマニュアルページでは、このオプションを次のように文書化します。

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

基本的な動作とは対照的に:

パイプの終了状態は、最後のコマンドの終了状態です。
パイプライン失敗オプションが有効になっていない場合。

関連情報