Рассмотрим команды
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
не применяется, как!
заявление явно проверяет состояние выхода.