Rozważ polecenia
eval false || echo ok
echo also ok
Zwykle spodziewalibyśmy się, że uruchomi to falsenarzędzie, a ponieważ status wyjścia jest różny od zera, to wykonamy echo oki 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 -edziała, OpenBSD shi kshpowł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 falsejest „błędem” (gdyby tak było, byłoby niezależne od set -ebycia aktywnym).
Wydaje się, że sposobem obejścia tego jest umieszczenie evalsub-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 okoba 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 okprzy string=falseuż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 falsesię zakończyć skrypt, nawet jeśli jest on częścią listy AND-OR lub instrukcji warunkowej? Nie zrobiłbym tego.
set -ejest ustawione, jeśli jest to prawidłowe zachowanie ... Zgadzam się, że sensowne jest, aby nie kończyć się instrukcją warunkową.
set -ewięc `()` jest odpowiedzią.
eval falsegeneruje niezerowy status, więc spodziewałbymset -esię, że w tym momencie zakończę skrypt. W przypadku!set -enie ma zastosowania, ponieważ!oświadczenie wyraźnie sprawdza status wyjścia.