Рассмотрим команды
eval false || echo ok
echo also ok
Обычно мы ожидаем, что это выполнит falseутилиту и, поскольку состояние выхода не равно нулю, затем выполнит echo okи echo also ok.
В всех POSIX-подобных оболочек , которые я использую ( ksh93, zsh, bash, dash, OpenBSD ksh, и yash), это то , что происходит, но все становится интересно , если мы включаем set -e.
Если set -eэто действует, OpenBSD shи kshоболочки (оба получены из pdksh) завершат сценарий при выполнении eval. Никакая другая оболочка не делает этого.
POSIX говорит, что ошибка в специальной встроенной утилите (такой как eval) должна привести к завершению неинтерактивной оболочки. Я не совсем уверен, является ли выполнение false«ошибкой» (если бы это было так, это было бы независимо от set -eактивности).
Способ обойти это, кажется, положить evalв субоболочку,
( eval false ) || echo ok
echo also ok
Вопрос в том, должен ли я делать это в правильном скрипте POSIX-версии или это ошибка в оболочке OpenBSD? Кроме того, что подразумевается под «ошибкой» в тексте POSIX, на который есть ссылка выше?
Дополнительный бит информации: Оболочки OpenBSD будут выполнять echo okкак с, так и без set -e в команде
eval ! true || echo ok
Мой оригинальный код выглядел как
set -e
if eval "$string"; then
echo ok
else
echo not ok
fi
который не будет выводиться not okс string=falseиспользованием оболочек OpenBSD (он будет завершен), и я не был уверен, что это было сделано из-за ошибки, из-за неправильного понимания или из-за чего-то еще.
eval falseзавершения сценария, даже если он является частью списка AND-OR или условного оператора? Я бы не стал.
set -eустановлено ли это, если это правильное поведение ... Я согласен, что имеет смысл не заканчиваться условным утверждением.
set -eпоэтому `()` - это ответ.
eval falseгенерирует ненулевой статус, поэтому я ожидаю,set -eчто сценарий будет прерван на этом этапе. В случае!set -eне применяется, как!заявление явно проверяет состояние выхода.