パイプ->while read でエラーハンドリング

command | while read …
do
  cmd1
  if [ $? -ne 0 ];
    echo "error!"
    exit 1
  fi
done

とかやってもexitしてくれないし、retrun 1 とかしても return してくれない。
whileループが子プロセスで実行されるかららしい。

しかし、exit とか return すると、ループの外に出てくれて、その時の戻り値が拾える。
つまり、

command | while read …
do
  cmd1
  if [ $? -ne 0 ];
    echo "error!"
    exit 1
  fi
done

echo $?

とした時の最後のecho は、ループ内の exit 1 が実行されれば1を返すし、ループが正常に終了したら0を返してくれる。

さらにパイプの前の command の戻り値も拾いたければ PIPESTATUS を見れば良い。

command | while read …
do
  cmd1
  if [ $? -ne 0 ];
    echo "error!"
    exit 1
  fi
done

for ret in ${PIPESTATUS[@]}
do
  [ $ret -ne 0 ] && exit $ret
done