目的
- パイプを使用したときのコマンドの終了コードについて詳しく知る。
※本記事の内容はbashの環境に依存します。同じbashでもこの方法だと解決しないことがあります。
この記事のターゲット
- ログを出力しているShellScriptの終了コードが欲しい方
- パイプより前の処理の終了コードが欲しい方
自分が困ったエピソード
-
test.sh
という名前のShellScriptのファイルを書いた。 - 実行するときのコンソールログと終了コードが欲しかった。
- 下記の様に当該スクリプトを実行した。
./test.sh 2>&1 | tee result.txt
- 実行後に
test.sh
が正常終了したか知りたかったため下記の終了コードを返すコマンドを実行
echo $?
- 終了コードは0が返ってきた。
- しかし
result.txt
を確認したところ、エラー終了していた。 - パイプを用いたコマンドを使用した場合に
echo $?
を実行するとtee result.txt
の終了コードが返ってきてしまう。
解決方法
- パイプで区切られた範囲の処理の終了コードが特定の配列に入るようになっているらしい。
${PIPESTATUS}という配列に結果が入っている。 - その配列から欲しい処理の終了コードを抜き取ってあげればOK
詳細
- 下記の様なパイプを多用した処理を例にする。
$ 処理1 | 処理2 | 処理3
-
一連の処理の終了コードはそれぞれ下記の様に配列${PIPESTATUS}に格納されている。
- 処理1の終了コード → 配列${PIPESTATUS}の0番目に格納
- 処理2の終了コード → 配列${PIPESTATUS}の1番目に格納
- 処理3の終了コード → 配列${PIPESTATUS}の2番目に格納
-
一連の処理の終了コードを出力したいときは下記の様に出力する。
- 処理1の終了コードをコンソールに表示 →
echo "${PIPESTATUS[0]}"
- 処理2の終了コードをコンソールに表示 →
echo "${PIPESTATUS[1]}"
- 処理3の終了コードをコンソールに表示 →
echo "${PIPESTATUS[2]}"
- 処理1の終了コードをコンソールに表示 →
まとめ
- パイプを使用した処理の終了コードについてまとめた。
- パイプで区切られた処理の終了コードは配列${PAPESTATUS}に順に格納される。