Rozważ polecenia
eval false || echo ok
echo also ok
Zwykle spodziewalibyśmy się, że uruchomi to false
narzędzie, a ponieważ status wyjścia jest różny od zera, to wykonamy echo ok
i echo also ok
.
We wszystkich POSIX-jak muszli używam ( ksh93
, zsh
, bash
, dash
, OpenBSD ksh
, a yash
), to jest to, co się dzieje, ale robi się ciekawie, jeśli pozwalają set -e
.
Jeśli set -e
działa, OpenBSD sh
i ksh
powłoki (oba pochodzące z pdksh
) zakończą skrypt podczas wykonywania eval
. Żadna inna powłoka tego nie robi.
POSIX mówi, że błąd w specjalnym wbudowanym narzędziu (takim jak eval
) powinien spowodować zakończenie nieinteraktywnej powłoki. Nie jestem do końca pewien, czy wykonanie false
jest „błędem” (gdyby tak było, byłoby niezależne od set -e
bycia aktywnym).
Wydaje się, że sposobem obejścia tego jest umieszczenie eval
sub-powłoki,
( eval false ) || echo ok
echo also ok
Pytanie brzmi, czy mam to zrobić w poprawnym skrypcie powłoki POSIX-owym, czy też jest to błąd w powłoce OpenBSD? Co również oznacza „błąd” w tekście POSIX połączonym z powyższym?
Dodatkowy bit informacji: Powłoki OpenBSD wykonają echo ok
oba polecenia z lub bez set -e
polecenia
eval ! true || echo ok
Mój oryginalny kod wyglądał
set -e
if eval "$string"; then
echo ok
else
echo not ok
fi
które nie byłyby generowane not ok
przy string=false
użyciu powłok OpenBSD (to by się zakończyło), i nie byłem pewien, czy to z założenia, przez pomyłkę, przez nieporozumienie, czy coś innego.
eval false
się zakończyć skrypt, nawet jeśli jest on częścią listy AND-OR lub instrukcji warunkowej? Nie zrobiłbym tego.
set -e
jest ustawione, jeśli jest to prawidłowe zachowanie ... Zgadzam się, że sensowne jest, aby nie kończyć się instrukcją warunkową.
set -e
więc `()` jest odpowiedzią.
eval false
generuje niezerowy status, więc spodziewałbymset -e
się, że w tym momencie zakończę skrypt. W przypadku!
set -e
nie ma zastosowania, ponieważ!
oświadczenie wyraźnie sprawdza status wyjścia.