ぐぐってもあまり情報が出てこなかったのでメモ。
Bashで 「$?」を使えば実行したコマンドの戻り値が取得できるのは有名。
$ false; echo $? 1 # falseの戻り値
Bashの場合、パイプされたコマンドの戻り値は 「PIPESTATUS」という配列に格納されることも、それなりに知られていると思う。
$ true | true | false $ echo ${PIPESTATUS[0]} ${PIPESTATUS[1]} ${PIPESTATUS[2]} 0 0 1 # true, true, falseの戻り値
ところが、バッククオートや 「$()」 によるコマンド置換の中で複数のコマンドをパイプし、その出力を何らかの変数に割り当て、かつ戻り値を調べようとするとうまく行かない。
RESULT=$( some_command | false | true ) echo ${PIPESTATUS[0]} ${PIPESTATUS[1]} ${PIPESTATUS[2]} 0 # 最後のtrueの戻り値
RESULT=$( some_command | false | true | false ) echo ${PIPESTATUS[0]} ${PIPESTATUS[1]} ${PIPESTATUS[2]} 1 # 最後のfalseの戻り値
上記の通り、コマンド置換中の最後のコマンドの戻り値以外は取得できない。
これは、コマンド置換がサブシェルを作成するものであり、PIPESTATUS 配列はそのサブシェル (コマンド置換内) でしか使用できないために起こるのだそうだ。
コマンド置換内のコマンドのうち、1件のみ (今の例ではsome_command) の戻り値が知りたいだけであれば、コマンド置換の中で exit statusを返してやれば良い。
RESULT=$( some_command | false | true | false; exit ${PIPESTATUS[0]} ) echo $? 0 # some_command の戻り値