Jedynym powodem, dla którego chcesz użyć $?jako argumentów [polecenia (niezależnie od tego, czy [polecenie to jest uruchamiane w części warunku ifinstrukcji, czy nie) jest, gdy chcesz rozróżnić konkretny status zwrotu, na przykład:
until
cmd
[ "$?" -gt 1 ]
do
something
done
Składnia dla tych wszystkich if, while, until... sprawozdanie jest
if cmd-list1
then cmd-list2
else cmd-list3
fi
Który działa, cmd-list2jeśli cmd-list1się powiedzie lub w cmd-list3inny sposób.
[ "$?" -eq 0 ]Komenda jest no-op. Ustawia $?na 0, jeśli $?wynosi 0, i $?na niezerową, jeśli była niezerowa.
Jeśli chcesz coś uruchomić, jeśli się cmdnie powiedzie, to:
if ! cmd
then ...
fi
Ogólnie rzecz biorąc, nie musisz majstrować przy tym, nie $?mówiąc już o tym, która wartość oznacza truelub false. Jedynymi przypadkami są, jak powiedziałem powyżej, jeśli musisz rozróżnić określoną wartość lub jeśli musisz ją zachować na później (na przykład, aby zwrócić ją jako wartość zwracaną funkcji), na przykład:
f() {
cmd; ret=$?
some cleanup
return "$ret"
}
Pamiętaj również, że pozostawienie zmiennej niecytowanej to operator split + glob. Przywołanie tego operatora tutaj nie ma sensu, więc powinno być:
[ "$?" -ne 0 ]
nie [ $? -ne 0 ], nie wspominając już o tym [$? -ne 0 ](który wywołałby [polecenie tylko wtedy, gdyby $IFSzawierał pierwszy znak $?).
Zauważ też, że sposobem Bourne'a na zdefiniowanie funkcji jest trzymanie function-name()się polecenia. To miało miejsce w każdym Bourne shell wyjątkiem jak bashi yash(i nowszych wersjach posh), które umożliwiają polecenia związek tylko (polecenia czym związek {...}lub (...)lub rzeczy jak for...done,if...fi ...
function foo { ... }to kshskładnia definicji funkcji. Nie ma powodu, dla którego chciałbyś go tutaj użyć.
Kod można zapisać przenośnie (POSIXly):
foo() (
cd -P -- "$FOOBAR" || return # what if the cd failed!
if
<some command>
then
echo 'OK!'
else
echo 'Nope!'
fi
)
Zauważ też, że cdbez -Pma bardzo specjalne znaczenie (obsługuje ścieżki, które zawierają ..komponenty inaczej niż jakiekolwiek inne polecenie), więc lepiej jest włączyć je do skryptów, aby uniknąć nieporozumień.
(ta funkcja zwraca, falsejeśli cdzawiedzie, ale nie, jeśli <some command>zawiedzie).
$?równa się 0 zifinstrukcją jest bezcelowe,ifoczekuje polecenia, a jeśli to polecenie powróci0, uruchamia kod w bloku. więc przywróciif true; then echo hello; fiecho, odkąd polecenietruepowróciło0.