【bash】コマンドの戻り値をワンライナーで確認するときの注意

bashスクリプトを書くとき、直前のコマンドの戻り値を見て条件分岐させたいことがよくある。戻り値は $? で取得できるのだが、このコマンドはいかなる場合でも直前のコマンドしか考慮してくれない。 例えば、以下は $? の誤った使い方である。

which aws | echo $?

この場合、 which aws | echo $? で一つのコマンドとみなされるため、 $? が表すのはその前のコマンドの戻り値となる。すなわち、パイプでつないだ前半部分のコマンドの戻り値を正しく判定できていない。例えば開発環境にsedコマンドが存在し、fooコマンドが存在しない場合、以下のようになる。

which foo # foo not found
which sed | echo $? # 1 
which sed # /usr/bin/sed
which foo | echo $? # 0

正しくはパイプではなく以下のように使う必要がある。

which sed; echo $?