Zastanawiałem się, jaki byłby najlepszy sposób sprawdzenia statusu wyjścia w instrukcji if, aby uzyskać echo określonego wyniku.
Myślę o tym
if [ $? -eq 1 ]
then
echo "blah blah blah"
fi
Mam również problem z tym, że instrukcja exit znajduje się przed instrukcją if po prostu dlatego, że musi mieć ten kod wyjścia. Wiem też, że robię coś złego, ponieważ wyjście oczywiście spowoduje wyjście z programu.
bash
shell
if-statement
error-handling
deadcell4
źródło
źródło
some_program; rc=$?; if [ ${rc} -eq 1 ] .... fi ; exit ${rc}
Odpowiedzi:
Każde uruchamiane polecenie ma status wyjścia.
Ta kontrola sprawdza status wyjścia polecenia, które zakończyło się przed uruchomieniem tego wiersza.
Jeśli chcesz aby skrypt zakończył się, gdy ten test zwróci wartość true (poprzednie polecenie nie powiodło się), umieść
exit 1
(lub cokolwiek) wewnątrz tegoif
bloku poecho
.To powiedziawszy, jeśli uruchamiasz komendę i chcesz przetestować jej dane wyjściowe za pomocą następującego, jest często prostsze.
Lub odwrócić to użycie
!
negacjiZauważ jednak, że żadna z nich nie obchodzi, jaki jest kod błędu. Jeśli wiesz, że zależy Ci tylko na określonym kodzie błędu, musisz to sprawdzić
$?
ręcznie.źródło
a_command || return 1
return
działa tylko w funkcji i skrypcie źródłowym . Potrzebujeszexit
drugiego przypadku (który robi zbyt wiele w funkcji i skrypcie źródłowym). Ale tak, to z pewnością rozsądny wzorzec, jeśli nie potrzebujesz żadnego konkretnego czyszczenia ani dodatkowych wyników.dash
, że domyślna nieinteraktywna powłoka w wielu współczesnych dystrybucjach linuksa nie dba o rozróżnienie między wykonanymi skryptami powłokireturn
iexit
wewnątrz nich.dash
wychodzi ze skryptu, nawet jeśli go używamreturn
.if <command>
przechodzi, jeśli kod wyjścia wynosi 0. W innym języku byłoby odwrotnieif ! some_command | some_other_command
zignoruje status some_command. Dwa najbardziej obejścia poleceń toset -o pipefail
(może zmienić funkcjonalność w innych częściach programu) lub przenieśćif
instrukcjęif [[ ${PIPESTATUS[0]} -ne 0 ]]
jako osobne polecenie uzupełniające (brzydkie, ale funkcjonalne). Jeśli używaszset -e
, będziesz również chciał dodać|| true
na końcu potoku podczas korzystania z drugiego rozwiązania, ponieważ usunięcie rury z oferowanego przez nią przepływu kontrolnegoif
spowodowałoby natychmiastowe wyjście.Zauważ, że kody wyjścia! = 0 są używane do zgłaszania błędów. Więc lepiej zrobić:
zamiast
źródło
dnf check-update
zwraca 0 (brak aktualizacji), 100 (dostępne aktualizacje) lub 1 (błąd).dnf
programiści wybrali ten sposób, to ich wybór. Ale ich wybór nie powoduje, że specyfikacja jest zepsuta :)$?
jest parametrem jak każdy inny. Możesz zapisać jego wartość do użycia przed ostatecznym wywołaniemexit
.źródło
Alternatywa dla jawnej
if
oświadczeniaMinimalnie:
test $? -eq 0 || echo "something bad happened"
Kompletny:
źródło
Aby dodać do pomocnej i szczegółowej odpowiedzi :
Jeśli musisz wyraźnie sprawdzić kod wyjścia, lepiej użyć operatora arytmetycznego
(( ... ))
, w ten sposób:Lub użyj
case
oświadczenia:Powiązana odpowiedź na temat obsługi błędów w Bash:
źródło