Поскольку я влюбляюсь в это, я хотел бы оставить записку.
Я нашел эту тему, потому что я должен переписать старый скрипт 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