203

コマンドをラップするシェルスクリプト(mvn clean install)があり、出力をログファイルにリダイレクトします。

#!/bin/bash
...
mvn clean install $@ | tee $logfile
echo $? # Does not show the return code of mvn clean install

エラーで失敗した場合mvn clean installは、ラッパーシェルスクリプトもそのエラーで失敗するようにします。ただし、すべての出力をteeにパイプしているため、の戻りコードにアクセスできませんmvn clean install。したがって、$?後でアクセスすると、常に0になります(teeが成功するため)。

コマンドにエラー出力を別のファイルに書き込んで後で確認しようとしましたが、mvnのエラー出力は常に空です(stdoutにのみ書き込むようです)。

mvn clean installのリターンコードを保持しながら、出力をログファイルにパイプするにはどうすればよいですか?

4

4 に答える 4

300

pipefail シェルオプションオプションをオンに設定して、必要な動作を得ることができます。

Bashリファレンスマニュアルから:

パイプラインの終了ステータスは、pipefailオプションが有効になっていない限り、パイプラインの最後のコマンドの終了ステータスです(Set Builtinを参照)。が有効になっている場合pipefail、パイプラインの戻りステータスは、ゼロ以外のステータスで終了する最後の(右端の)コマンドの値です。すべてのコマンドが正常に終了した場合はゼロになります。

例:

$ false | tee /dev/null ; echo $?
0
$ set -o pipefail
$ false | tee /dev/null ; echo $?
1

元のパイプ設定を復元するには:

$ set +o pipefail
于 2011-07-29T11:05:14.987 に答える
200

を実行しているので、次の代わりに$PIPESTATUS変数bashを使用できます。$?

mvn clean install $@ | tee $logfile
echo ${PIPESTATUS[0]}
于 2011-07-29T10:42:19.487 に答える
17

mvnコマンドを実行して、終了コードをキャッシュすることができます...私の例では「false」コマンドを使用します。

$ { false ; echo $? > /tmp/false.status ; } | tee $logfile
$ cat /tmp/false.status
1

そうすれば、ステータスファイルの内容を使用してさらに決定を下すことができます。

これを達成するためのもっと雄弁な方法があるかどうか今、私は興味があります。

于 2011-07-29T10:55:59.697 に答える
5

回避策(注:perfer @Fredericのソリューション):

f=`mktemp`
(mvn clean install $@; echo $?>$f) | tee $logfile
e=`cat $f` #error in variable e
rm $f
于 2011-07-29T10:56:00.783 に答える