bashのpipefailオプション
以前から set -e
を使って、エラー時に実行を止めるシェルをよく書いてましたが、
パイプでコマンドを繋げた場合、最後のコマンドにしか効かないことを今更ながら知ったのでメモ。
例えば、以下のシェルはsl
なんてコマンドは存在しないので、そこでエラーになり止まると思いきや、、、
#!/bin/bash set -e sl | echo "パイプの最後のコマンド" echo "戻り値を確認:$?" echo "ここには来ないはず"
後続の処理が実行されてしまいました。
$ bash /tmp/sete.sh パイプの最後のコマンド /tmp/sete.sh: 行 5: sl: コマンドが見つかりません 戻り値を確認:0 ここには来ないはず
パイプの最後のechoが正常終了してるので、パイプ実行直後の$?
が0となり後続が実行されるようです。
次にset -e
の行をset -eo pipefail
に変えて実行してみます。
$ bash /tmp/sete.sh
/tmp/sete.sh: 行 5: sl: コマンドが見つかりません
パイプの最後のコマンド
今度はパイプの最後までは実行されるが、後続処理は実行されませんでした。
上記を実行直後に$?
を確認すると、コマンドが見つからない旨のエラーコード127が返っているので処理が止まるようです。
今度は、2箇所でエラーになるように絶対にヒットしないgrep detarame
を追加してみます。
sl | grep detarame | echo "パイプの最後のコマンド"
$ bash /tmp/sete.sh
パイプの最後のコマンド
/tmp/sete.sh: 行 5: sl: コマンドが見つかりません
こんどは実行直後の$?
は1だったので、最後にエラーになったgrepコマンドの戻り値がパイプの戻り値になるようです。