落ちるのでメモを書きたいと思います。古いスレッドをPOSIX互換にするために書き直す必要があるため、このスレッドを見つけました。これは基本的に、次のようなコードを書き直すことにより、POSIXによって導入されたパイプ/サブシェルの問題を回避することを意味します。
some_command | read a b c
に:
read a b c << EOF
$(some_command)
EOF
そして、このようなコード:
some_command |
while read a b c; do
# something
done
に:
while read a b c; do
# something
done << EOF
$(some_command)
EOF
しかし、後者は空の入力では同じように動作しません。古い表記では、whileループは空の入力では入力されませんが、POSIX表記ではそうなります!EOFの前の改行によるものだと思います。古い表記のように動作するPOSIXコードは次のようになります。
while read a b c; do
case $a in ("") break; esac
# something
done << EOF
$(some_command)
EOF
ほとんどの場合、これで十分です。しかし、残念ながら、some_commandが空の行を出力する場合、これはまだ古い表記とまったく同じようには動作しません。古い表記ではwhile本体が実行され、POSIX表記では本体の前で中断します。
これを修正する方法は次のようになります。
while read a b c; do
case $a in ("something_guaranteed_not_to_be_printed_by_some_command") break; esac
# something
done << EOF
$(some_command)
echo "something_guaranteed_not_to_be_printed_by_some_command"
EOF