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