Wyjdź z kodu na końcu skryptu bash

22

Jestem zdezorientowany co do znaczenia kodu zakończenia na końcu skryptu bash: Wiem, że kod wyjścia 0 oznacza, że ​​zakończył się powodzeniem i że istnieje wiele innych numerów kodów zakończenia (127, jeśli się nie mylę?)

Moje pytanie dotyczy tego, czy widząc kod wyjścia 0 na końcu skryptu, czy wymusza kod wyjścia jako 0, nawet jeśli skrypt się nie powiedzie, czy też ma inne znaczenie?

Odpadł
źródło
2
Jeśli skrypt kończy się na exit 0, zakończy działanie z kodem wyjścia 0, niezależnie od tego, co dzieje się w skrypcie.
Hatclock
@Hatclock dlaczego nie opublikowałeś swojej pełnej odpowiedzi? jako komentarz nie mogę tego zaznaczyć i nie sądzę, że dostajesz fałszywe punkty internetowe za udzielanie odpowiedzi (prawda?) Tylko myśl ... (uznanie za szybką odpowiedź)
odpadł
1
Jestem na stacji kolejowej w telefonie, nie bardzo lubię pisać za dużo na telefonie. ilkkachu wydaje się jednak mieć dobrą odpowiedź!
Hatclock
Zobacz także: Domyślny kod wyjścia po zakończeniu procesu?
Stéphane Chazelas,
2
@Hatclock Nie, wcale nie. Jeśli skrypt kończy się na exit 0, wyjdzie z kodem 0 tylko wtedy, gdy ta ostatnia instrukcja została wykonana. Jedynym skutkiem exit 0na końcu skryptu jest zwrócenie 0 zamiast statusu z poprzedniej instrukcji.
Gilles „SO- przestań być zły”

Odpowiedzi:

22

Wbudowane polecenie exitwychodzi z powłoki (z odwołania Basha ):

exit [n]
Wyjdź z powłoki, zwracając status n rodzicowi powłoki. Jeśli n zostanie pominięte, stanem wyjścia jest status ostatniego wykonanego polecenia. Wszelkie pułapki na EXIT są wykonywane przed zakończeniem powłoki.

Uruchomienie do końca pliku również kończy działanie, zwracając kod powrotu ostatniego polecenia, więc tak, finał exit 0sprawi, że skrypt zakończy działanie z udanym statusem, niezależnie od statusu wyjścia poprzednich poleceń. (To znaczy, zakładając, że skrypt dojdzie do finału exit.) Na końcu skryptu można również użyć truelub :uzyskać zerowy kod wyjścia.

Oczywiście częściej używasz exitod wewnątrz, ifaby zakończyć skrypt w środku.

Powinny wypisać 1 ( $?zawiera kod wyjścia zwrócony przez poprzednie polecenie):

sh -c "false" ; echo $?
sh -c "false; exit" ; echo $?

Chociaż powinno to wydrukować 0:

sh -c "false; exit 0" ; echo $?

Nie jestem pewien, czy koncepcja skryptu „zawodzi” podczas wykonywania exitma sens, ponieważ całkiem możliwe jest, że niektóre polecenia uruchamiane przez skrypt nie działają, ale sam skrypt się powiedzie. Od autora skryptu zależy, który z nich zakończy się sukcesem, a co nie.

Ponadto standardowy zakres kodów wyjścia wynosi 0..255. Kody powyżej 127 są używane przez powłokę do wskazania procesu zakończonego sygnałem, ale można je zwrócić w zwykły sposób. waitWywołanie systemowe faktycznie zwraca szerszą wartość, z bitami stanu spoczynku zawierający określonych przez system operacyjny.

ilkkachu
źródło
Fajnie, nie wiedziałem o numeracji 8-bitowych kodów wyjścia. Dzięki!
odpadł
Zauważ, że gdy proces zostanie zabity, nie kończy się kodem wyjścia> 127. Po prostu niektóre powłoki ustawione $?w tym przypadku na 128 + signum. Zobacz Domyślny kod wyjścia po zakończeniu procesu? dla szczegółów.
Stéphane Chazelas,
exit 0zwróci tylko 0, jeśli wyjście jest wykonane. (może wyjść inną drogą).
ctrl-alt-delor
18

0 oznacza sukces, dodatnie liczby całkowite oznaczają niepowodzenie. Istnieje 255 różnych kodów błędów, ale wartości 126 i wyższe są zarezerwowane, aby wskazać, że program nie mógł się uruchomić (126 lub 127) lub został zabity przez sygnał (129 i więcej). Zobacz Domyślny kod wyjścia po zakończeniu procesu? oraz Jakich wartości powrotu / wyjścia można użyć w funkcjach / skryptach bash? po więcej informacji.

Status wyjścia skryptu powłoki to status wyjścia ostatniego polecenia wykonanego przez skrypt. Na przykład

#!/bin/sh
somecommand

zwraca status wyjścia somecommand, natomiast

#!/bin/sh
somecommand
exit 0

zwraca 0 niezależnie od tego, co somecommandzwróciło. Ten drugi skrypt można również napisać

#!/bin/sh
somecommand
true

Umieszczenie exit 0na końcu skryptu niekoniecznie powoduje, że zwraca on 0. To powoduje, że zwraca 0, gdy skrypt osiągnie koniec. Na przykład poniższy skrypt zawsze zwraca 3:

#!/bin/sh
exit 3
exit 0

Poniższy skrypt zawsze zwraca kod błędu, oprócz wyświetlania komunikatu o błędzie składni:

#!/bin/sh
}
exit 0

Poniższy skrypt zwraca 1 lub 0 w zależności od pierwszego argumentu:

#!/bin/sh
if [ "$1" = "foo" ]; then
  exit 1
fi
exit 0

Poniższy skrypt zwraca status somecommand, ponieważ set -epowoduje zamknięcie skryptu w przypadku somecommandniepowodzenia:

#!/bin/sh
set -e
somecommand
exit 0
Gilles „SO- przestań być zły”
źródło