Znaczenie wyjścia 0, wyjścia 1 i wyjścia 2 w skrypcie bash

49

Robię ćwiczenia.

Napisz skrypt, który otrzyma argument miesiąca jako argument i przetłumaczy ten numer na nazwę miesiąca. Wynik zostanie wydrukowany na standardowym wyjściu.

Stworzyłem rozwiązanie:

#test for number of argument

if [ "$#" -eq 0 ] ; 
then
   echo -e "No argument."
   echo -e "Write a number between 1 and 12."
   exit 1
elif [ "$#" -gt 1 ] ;
then
   echo -e "More than 1 argument."
   echo -e "Write a number between 1 and 12."
   exit 1
else

   numb=$1
   case "$numb" in
      1) echo "Month: January";;
      2) echo "Month: February";;
      3) echo "Month: March";;
      4) echo "Month: April";;
      5) echo "Month: May";;
      6) echo "Month: June";;
      7) echo "Month: July";;
      8) echo "Month: August";;
      9) echo "Month: September";;
     10) echo "Month: October";;
     11) echo "Month: November";;
     12) echo "Month: December";;
      *) echo -e "You wrote a wrong number. Try again with writing number between 1 and 12.";;

   esac
fi
exit 2
exit 0

Co exit 1, exit 0i co exit 2oznacza i dlaczego ich używamy?

andrej benedičič
źródło
5
Pomyślnie wykonany kod powinien zakończyć się kodem 0. Inne wartości wskazują na błąd. Zobacz na przykład kody zakończenia o specjalnych znaczeniach
V. Olsen,
2
Skrypt bash jest jak kino, istnieją różne. Instrukcje wyjścia oznaczają lokalizację wyjść dla interpretera bash. Po uruchomieniu skryptu interpreter musi działać do najbliższego wyjścia.
Depressed
5
Jeśli to jest kod, który napisałeś, to dlaczego użyłeś instrukcji, których nawet nie rozumiesz?
Dmitrij Grigoriew
5
1) Przyjąłeś odpowiedź zaraz po opublikowaniu pytania. Daj 24 godziny na oczekiwanie na jeszcze lepsze odpowiedzi. 2) Przyjęta odpowiedź jest błędna i wprowadza w błąd. Prawidłowa odpowiedź brzmi: „nie ma domyślnego znaczenia dla kodów wyjścia (poza 0 = sukces); ty jako programista skryptów definiujesz semantykę”. 3) Jeśli stworzyłeś ten skrypt, dlaczego dodałeś polecenia wyjścia (wszystkie są logicznie zbędne lub mogą zwinąć się do „exit 1”, ponieważ i tak używasz if-else).
AnoE

Odpowiedzi:

58

Oto jedno dobre odniesienie do kodów wyjścia powłoki :

Exit code 0        Success
Exit code 1        General errors, Miscellaneous errors, such as "divide by zero" and other impermissible operations
Exit code 2        Misuse of shell builtins (according to Bash documentation)        Example: empty_function() {}

Zastrzeżenie: użycie właściwego kodu wyjścia nie jest wymagane i nie jest egzekwowane przez powłokę. Programiści mogą zignorować wskazówki, jeśli uznają to za mądre.

użytkownik535733
źródło
8
Bądź jednak ostrożny. To, co oznacza kod zakończenia, zależy wyłącznie od twórców programu.
muru
Ponadto, chociaż powiązane źródło, Advanced Bash Scripting Guide, twierdzi, że pokazuje „ Reserved Exit Codes” (podkreślenie w oryginale), twierdzenie to jest zarówno niewymienione, jak i całkowicie fałszywe .
Eliah Kagan
23

Używanie exiti liczba to przydatny sposób sygnalizowania wyniku skryptu. Naśladuje sposób, w jaki polecenia bash generują kod powrotu. W przypadku poleceń bash kod powrotu 0 zwykle oznacza, że ​​wszystko przebiegło pomyślnie bez błędów. exitpowoduje również zatrzymanie wykonywania skryptu w tym momencie i powrót do wiersza poleceń.

Każdy kod powrotu większy niż 0 wskazuje na jakiś rodzaj błędu, chociaż czasami błąd nie jest krytyczny, dla każdego polecenia powinna istnieć możliwość znalezienia dokumentacji wyjaśniającej, co oznacza każdy kod powrotu.

Możesz uzyskać kod powrotu ostatniej komendy bash, używając zmiennej powłoki w następujący $?sposób:

$ echo "something"
something
$ echo $?
0
$ cp
cp: missing file operand
Try 'cp --help' for more information.
$ echo $?
1

Gdy używasz tego w skrypcie, możesz zapytać o kod powrotu w ten sam sposób, gdy zakończy się wykonywanie. Przekonasz się więc, że:

exit 2
exit 0

Jest to trochę bez znaczenia, ponieważ nigdy nie możesz dotrzeć do tej exit 0części.

Arroniczny
źródło
3

Wszystko samo w sobie exitoznacza wartość wyjściową równą zero lub pomyślne zakończenie skryptu. Nie musisz dodawać argumentu zero do polecenia exit, aby wskazać pomyślne zakończenie. Skrypt może (lub prawdopodobnie zakończy) pomyślnie zakończyć działanie, chociaż testuje pod kątem błędnych warunków. W takim przypadku chcesz, aby zakończyło się z warunkiem błędu (lub 1).

echo -e "Enter numbers 1-4" \c"
read NUM
case $NUM in 
    1) echo "one";;
    2) echo "two";;
    3) echo "three";;
    4) echo "four";;
    *) echo "invalid answer"
       exit 1;;
esac

exitKomenda w ostatnim wierszu nie musi być tam w ogóle. Można go wywołać z zerowym lub w ogóle nie wywołać. Bez podania argumentu 1 dla polecenia wyjścia odpowiedź we wszystkich tych przypadkach echo $?będzie równa zero.

Jeśli jednak podasz argument 1 dla polecenia wyjścia, odpowiedź echo $?będzie równa 1. Użyj więc argumentu 1 dla polecenia wyjścia, jeśli chcesz określić, że skrypt zakończył działanie z warunkiem błędu.

geekasaurus
źródło