Jaké jsou minimální a maximální hodnoty následujících ukončovacích kódů v Linuxu:
- Ukončovací kód vrácený z binárního spustitelného souboru (například:program C
). - Ukončovací kód vrácený bash skriptem (při volání
exit
). - Ukončovací kód vrácený funkcí (při volání
return
).
Myslím, že je to mezia
255
.
Přijatá odpověď:
Číslo předané do _exit()
/exit_group()
systémové volání (někdy označované jako výstupní kód abyste se vyhnuli nejednoznačnosti se stavem opuštění což také odkazuje na kódování buď výstupního kódu nebo čísla signálu a dalších informací v závislosti na tom, zda byl proces ukončen nebo ukončen normálně) je typu int
, takže na systémech podobných Unixu, jako je Linux, obvykle 32bitové celé číslo s hodnotami od -2147483648 (-2) do 2147483647 (2-1).
Nicméně na všech systémech, když nadřazený proces (nebo podřízený subreaper nebo init
pokud rodič zemřel) používá wait()
, waitpid()
, wait3()
, wait4()
systémová volání pro jeho načtení, je k dispozici pouze jeho spodních 8 bitů (hodnoty 0 až 255 (2-1)).
Při použití waitid()
API (nebo obslužný program signálu na SIGCHLD), na většině systémů (a jak nyní POSIX jasněji vyžaduje ve vydání standardu z roku 2016 (viz _exit()
specifikace)), je k dispozici celé číslo (v si_status
pole vrácené struktury). To zatím není případ Linuxu, který také zkrátí číslo na 8 bitů pomocí waitid()
API, i když se to pravděpodobně v budoucnu změní.
Obecně byste chtěli používat pouze hodnoty 0 (obecně znamená úspěch) až 125, protože mnoho shellů používá ve svém $?
hodnoty vyšší než 128 znázornění stavu opuštění pro zakódování čísla signálu zabíjeného procesu a 126 a 127 pro speciální podmínky.
Možná budete chtít použít 126 až 255 na exit()
znamená totéž, co pro shell $?
(jako když skript provede ret=$?; ...; exit "$ret"
). Použití hodnot mimo 0 -> 255 obecně není užitečné. Obecně byste to udělali, pouze pokud víte, že rodič použije waitid()
API na systémech, které se nezkracují, a vy náhodou potřebujete 32bitový rozsah hodnot. Všimněte si, že pokud provedete exit(2048)
například, že to budou rodiče považovat za úspěch pomocí tradičního wait*()
API.
Více informací na:
- Výchozí kód ukončení při ukončení procesu?
Tyto otázky a odpovědi by snad měly odpovědět na většinu vašich dalších otázek a objasnit, co znamená stav odchodu . Ještě přidám pár věcí:
Proces nelze ukončit, pokud není zabit nebo volá _exit()
/exit_group()
systémová volání. Když se vrátíte z main()
v C
, knihovna libc zavolá toto systémové volání s návratovou hodnotou.
Většina jazyků má exit()
funkce, která toto systémové volání zabalí, a hodnota, kterou nabývají, je-li nějaká, je obecně předána stejně jako systémové volání. (všimněte si, že tyto obecně dělají více věcí, jako je čištění pomocí exit()
v C funkce, která vyprázdní vyrovnávací paměti stdio, spustí atexit()
háčky…)
To je alespoň případ:
$ strace -e exit_group awk 'BEGIN{exit(1234)}'
exit_group(1234) = ?
$ strace -e exit_group mawk 'BEGIN{exit(1234)}'
exit_group(1234) = ?
$ strace -e exit_group busybox awk 'BEGIN{exit(1234)}'
exit_group(1234) = ?
$ echo | strace -e exit_group sed 'Q1234'
exit_group(1234) = ?
$ strace -e exit_group perl -e 'exit(1234)'
exit_group(1234) = ?
$ strace -e exit_group python -c 'exit(1234)'
exit_group(1234) = ?
$ strace -e exit_group expect -c 'exit 1234'
exit_group(1234) = ?
$ strace -e exit_group php -r 'exit(1234);'
exit_group(1234) = ?
$ strace -e exit_group zsh -c 'exit 1234'
exit_group(1234)
Občas uvidíte některé, kteří si stěžují, když použijete hodnotu mimo 0-255:
$ echo 'm4exit(1234)' | strace -e exit_group m4
m4:stdin:1: exit status out of range: `1234'
exit_group(1) = ?
Některé shelly si stěžují, když použijete zápornou hodnotu:
$ strace -e exit_group dash -c 'exit -1234'
dash: 1: exit: Illegal number: -1234
exit_group(2) = ?
$ strace -e exit_group yash -c 'exit -- -1234'
exit: `-1234' is not a valid integer
exit_group(2) = ?
POSIX ponechává chování nedefinované, pokud je hodnota předána do exit
speciální vestavěný je mimo 0->255.
Některé shelly vykazují neočekávané chování, pokud tak učiníte:
-
bash
(amksh
ale nepdksh
na kterém je založen) se sám rozhodne zkrátit hodnotu na 8 bitů:$ strace -e exit_group bash -c 'exit 1234' exit_group(210) = ?
Takže pokud v těchto shellech chcete skončit s hodnotou mimo 0-255, musíte udělat něco jako:
exec zsh -c 'exit -- -12345' exec perl -e 'exit(-12345)'
To znamená provést další příkaz ve stejném procesu, který může zavolejte systémové volání s požadovanou hodnotou.
-
jak bylo zmíněno v dalších otázkách a odpovědích,
ksh93
má nejpodivnější chování pro výstupní hodnoty od 257 do 256+max_signal_number, kde místo voláníexit_group()
, zabije se odpovídajícím signálem¹.$ ksh -c 'exit "$((256 + $(kill -l STOP)))"' zsh: suspended (signal) ksh -c 'exit "$((256 + $(kill -l STOP)))"'
a jinak zkrátí číslo jako
bash
/mksh
.