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