Porque eu me apaixono por isso, gostaria de deixar uma nota. Encontrei este tópico, porque tenho que reescrever um script sh antigo para ser compatível com POSIX. Isso basicamente significa contornar o problema de pipe / subshell introduzido pelo POSIX, reescrevendo o código da seguinte maneira:
some_command | read a b c
para dentro:
read a b c << EOF
$(some_command)
EOF
E código como este:
some_command |
while read a b c; do
# something
done
para dentro:
while read a b c; do
# something
done << EOF
$(some_command)
EOF
Mas o último não se comporta da mesma maneira na entrada vazia. Com a notação antiga, o loop while não é inserido na entrada vazia, mas na notação POSIX, é! Eu acho que é devido à nova linha antes do EOF, que não pode ser omitida. O código POSIX que se comporta mais como a notação antiga é assim:
while read a b c; do
case $a in ("") break; esac
# something
done << EOF
$(some_command)
EOF
Na maioria dos casos, isso deve ser bom o suficiente. Infelizmente, isso ainda não se comporta exatamente como a notação antiga, se some_comand imprime uma linha vazia. Na notação antiga, o corpo while é executado e na notação POSIX, quebramos na frente do corpo.
Uma abordagem para corrigir isso pode ser assim:
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