Jakie są minimalne i maksymalne wartości następujących kodów wyjścia w systemie Linux:
- Kod wyjścia zwrócony z binarnego pliku wykonywalnego (na przykład: program w języku C).
- Kod wyjścia zwrócony ze skryptu bash (podczas wywoływania
exit
). - Kod wyjścia zwrócony z funkcji (podczas wywoływania
return
). Myślę, że to jest pomiędzy0
i255
.
linux
executable
function
exit-status
użytkownik 271801
źródło
źródło
return
To oczywiście wbudowana powłoka.bash
powłoki. Niektóre inne powłokizsh
mogą zwracać dowolną 32-bitową wartość ze znakiem, jak dlaexit
. Niektórzy lubiąrc
lubes
mogą zwracać dane dowolnego obsługiwanego typu (skalar lub lista). Szczegółowe informacje można znaleźć w powiązanych pytaniach i odpowiedziach.Odpowiedzi:
Numer przekazywany do wywołania systemowego
_exit()
/exit_group()
(czasami nazywany kodem wyjścia, aby uniknąć niejednoznaczności ze statusem wyjścia, który odnosi się również do kodowania kodu wyjścia lub numeru sygnału i dodatkowych informacji w zależności od tego, czy proces został zabity, czy zakończony normalnie ) jest typuint
, więc w systemach uniksopodobnych, takich jak Linux, zwykle jest to 32-bitowa liczba całkowita o wartościach od -2147483648 (-2 31 ) do 2147483647 (2 31 -1).Jednak we wszystkich systemach, kiedy proces nadrzędny (lub subreaper dziecko lub
init
jeśli rodzic zmarł) używawait()
,waitpid()
,wait3()
,wait4()
wywołania systemowe, aby je odzyskać, tylko dolne 8 bitów to są dostępne (wartości od 0 do 255 (2 8 - 1)).Podczas korzystania z
waitid()
interfejsu API (lub procedury obsługi sygnału w SIGCHLD) w większości systemów (a ponieważ POSIX bardziej wyraźnie wymaga tego w wersji standardowej 2016 (patrz_exit()
specyfikacja )) dostępna jest pełna liczba (wsi_status
polu zwracanej struktury ). Nie jest tak jednak w przypadku Linuksa, który również zmniejsza liczbęwaitid()
interfejsów API do 8 bitów , choć może się to zmienić w przyszłości.Ogólnie rzecz biorąc, chciałbyś używać tylko wartości 0 (ogólnie oznacza sukces) tylko do 125, ponieważ wiele powłok używa wartości powyżej 128 w ich
$?
reprezentacji statusu wyjścia do zakodowania numeru sygnału zabijanego procesu oraz 126 i 127 dla specjalnych warunki.Możesz użyć 126 do 255,
exit()
aby oznaczać to samo, co w przypadku powłoki$?
(tak jak w przypadku skrypturet=$?; ...; exit "$ret"
). Używanie wartości spoza 0 -> 255 na ogół nie jest przydatne. Zasadniczo zrobiłbyś to tylko wtedy, gdy wiesz, że rodzic użyjewaitid()
interfejsu API w systemach, które nie są obcinane, a zdarza się, że potrzebujesz 32-bitowego zakresu wartości. Pamiętaj, że jeśli wykonaszexit(2048)
np., Rodzice będą postrzegać to jako sukces przy użyciu tradycyjnychwait*()
interfejsów API.Więcej informacji na:
Mam nadzieję, że pytania i odpowiedzi powinny odpowiedzieć na większość pozostałych pytań i wyjaśnić, co oznacza status wyjścia . Dodam jeszcze kilka rzeczy:
Proces nie może zostać zakończony, dopóki nie zostanie zabity lub nie wywoła wywołań
_exit()
/exit_group()
system. Po powrocie zmain()
wC
, zaproszeń libc tego wywołania systemowego z wartości zwracanej.Większość języków ma
exit()
funkcję, która otacza to wywołanie systemowe, oraz wartość, którą przyjmują, jeśli są one generalnie przekazywane tak samo jak wywołanie systemowe. (zauważ, że generalnie robią więcej rzeczy, takich jak czyszczenie wykonane przezexit()
funkcję C, która opróżnia bufory stdio, uruchamiaatexit()
haki ...)Tak jest w przypadku co najmniej:
Czasami widzisz osoby, które narzekają, gdy używasz wartości spoza 0-255:
Niektóre pociski skarżą się, gdy użyjesz wartości ujemnej:
POSIX pozostawia zachowanie niezdefiniowane, jeśli wartość przekazana do
exit
specjalnego wbudowanego kodu jest poza 0-> 255.Niektóre powłoki wykazują pewne nieoczekiwane zachowania, jeśli:
bash
(mksh
ale niepdksh
na którym się opiera) bierze na siebie obcinanie wartości do 8 bitów:Więc w tych powłokach, jeśli chcesz wyjść z wartością spoza 0-255, musisz zrobić coś takiego:
To jest wykonanie innej komendy w tym samym procesie, która może wywołać wywołanie systemowe o żądanej wartości.
jak wspomniano w innych
ksh93
pytaniach i odpowiedziach, ma najdziwniejsze zachowanie dla wartości wyjściowych od 257 do 256 + max_signal_number gdzie zamiast wywoływaćexit_group()
, zabija się odpowiednim sygnałem¹.i inaczej obcina liczbę, np .
bash
/mksh
.¹ Prawdopodobnie zmieni się to w następnej wersji. Teraz, gdy rozwój
ksh93
został przejęty jako wysiłek społeczności poza AT&T, zachowanie to, choć w jakiś sposób wspierane przez POSIX, zostaje cofnięteźródło
si_status
systemie Linux?int
co najmniej 16 bitów, POSIX mniej więcej wymaga co najmniej 32 bitów, a środowiska programowania muszą mieć uint32_t . Nie wiem, czy Linux obsługuje jakiekolwiek środowisko programistyczne, w którym ints jest czymś innym niż 32 bity, nigdy nie spotkałem żadnego.Minimum to
0
i jest to uważane za wartość sukcesu. Wszystkie pozostałe są porażką. Maksimum jest255
także znane jako-1
.Reguły te dotyczą zarówno skryptów i innych plików wykonywalnych, jak i funkcji powłoki.
Większe wartości wynikają z modulo 256.
źródło
bash
lub innych najczęściej używanych) kod wyjścia przekazywany doexit
wbudowanego nie jest traktowany jako modulo-256, a zamiast tego powoduje błąd. (Na przykład, wspólne nieexit -1
jest w rzeczywistości przenośnym odpowiednikiemexit 255
większości powłok). A to, czyexit(-1)
na poziomie C jest równoważne,exit(255)
jest szczegółem, który de facto na pewno zadziała, ale zależy od zachowania określonego dla implementacji (chociaż nie jest to problem w nowoczesnych systemach, których prawdopodobnie będziesz używać w praktyce).exit(1)
parametr do 8 bitów.To wygląda tak prosto, ale o nieszczęście.
Język C (i podążanie za tym większością innych języków bezpośrednio lub pośrednio) wymaga, aby powrót z
main
był równoważny wywołaniuexit
z tym samym argumentem co wartość zwracana. Jest to liczba całkowita (typ zwracany jest bardzo wyraźnieint
), więc w zasadzie zakres byłbyINT_MIN
doINT_MAX
.Jednak POSIX stwierdza, że tylko 8 najniższych przekazanych bitów
exit
zostanie udostępnionych oczekującemu procesowi nadrzędnemu, dosłownie tak, jakby to był „status & 0xFF” .W praktyce więc kodem wyjścia jest (wciąż podpisana) liczba całkowita, w której ustawionych jest tylko 8 najniższych bitów.
Minimalna będzie więc -128, a maksymalna 127. Poczekaj, to nieprawda. Będzie to od 0 do 255.Ale niestety, oczywiście nie może to być takie proste . W praktyce Linux (a raczej bash) robi to inaczej . Prawidłowy zakres kodów powrotu wynosi od 0 do 255 (tj. Bez znaku).
Aby być bezpiecznym, jeśli chodzi o unikanie pomyłek, prawdopodobnie dobrze jest po prostu założyć, że kody zwrotne są niepodpisane i przesłać wszystko, co wrócisz
wait
do niepodpisanego. W ten sposób jest to spójne z tym, co widzisz w powłoce. Ponieważ najwyższe bity (w tym najważniejszy) są usuwane, nie jest to nawet „złe”, ponieważ chociaż technicznie podpisane, rzeczywiste wartości są zawsze niepodpisane (ponieważ bit znaku nigdy nie jest ustawiony).Pomaga także uniknąć typowego błędu porównywania kodu wyjściowego
-1
, z którego z dziwnych powodów wydaje się, że nie pojawia się nawet po wyjściu z programu-1
(no cóż, dlaczego!).O twoim ostatnim punkcie, powracaniu z funkcji, jeśli ta funkcja się zdarzy
main
, to patrz wyżej. W przeciwnym razie zależy to od typu zwracanego przez funkcję, może to być w zasadzie cokolwiek (w tymvoid
).źródło
waitid()
został wprowadzony.waitid()
robi to samo, nieco inaczej. Oczekuje na konkretny identyfikator lub dowolny wątek i zapisuje wyniki do wskazanejsiginfo_t
struktury, w którejsi_status
jestint
(tak ... podpisany , po prostu taki sam). Mimoexit()
to przechodzi tylko najniższe 8 bitów, więc ... absolutnie to samo pod maską.exit()
przekazuje wszystkie 32 bity parametru do jądra iwaitid()
zwraca wszystkie 32 bity z kodu wyjścia. Może sprawdziłeś na Linuxie, gdzie nikt nie chce naprawiać błędów. Jeśli mi nie wierzysz, sprawdź system operacyjny zgodny z POSIX ...exit
, w szczególności drugą linię pod „Opis”, która stanowi: „chociaż tylko 8 najmniej znaczących bitów (to znaczy status i 0377) będzie dostępnych dla oczekującego procesu nadrzędnego „ . Tak działa implementacja zgodna - najniższe 8 bitów, a nie 32. Czy masz odniesienie do przekazywania 32 bitów?waitid()
asiginfo_t
struktura przekazana do programuSIGCHLD
obsługi wszystkie 32 bity odexit()
parametru.Kody wyjścia z dowolnego procesu - czy to binarnego pliku wykonywalnego, skryptu powłoki, czy cokolwiek innego - mieszczą się w zakresie od 0 do 255. Można przekazać większą wartość
exit()
, ale tylko 8 niższych bitów statusu jest udostępnianych inne procesy poprzezwait()
.Funkcja AC może być zadeklarowana jako zwracająca prawie dowolny typ. Granice jego wartości zwracanej są całkowicie określane przez ten typ: na przykład od -128 do 127 dla zwracanej funkcji
signed char
lub od 0 do 4,2 miliarda dla zwracanej funkcjiunsigned int
lub dowolna liczba zmiennoprzecinkowa doinf
zwracanej funkcji włączniedouble
. I że nie liczy typy non-numeryczne, jakvoid *
albostruct
...źródło