Оскільки я підпадаю під це, я хотів би залишити ноту. Я знайшов цю тему, тому що я повинен переписати старий скрипт sh, щоб бути сумісним 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 друкує порожній рядок. У старих позначеннях час виконання тіла виконується, а в позначеннях 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