Il numero passato alla chiamata _exit()/ exit_group()system (a volte indicato come codice di uscita per evitare l'ambiguità con lo stato di uscita che si riferisce anche a una codifica del codice di uscita o del numero del segnale e informazioni aggiuntive a seconda che il processo sia stato terminato o chiuso normalmente ) è di tipo int, quindi su sistemi simili a Unix come Linux, in genere un numero intero a 32 bit con valori compresi tra -2147483648 (-2 31 ) e 2147483647 (2 31 -1).
Tuttavia, su tutti i sistemi, quando il processo padre (o la subreaper bambino o initse il genitore è morto) utilizza i wait(), waitpid(), wait3(), wait4()chiamate di sistema per recuperarla, solo gli ultimi 8 bit di esso sono disponibili (valori da 0 a 255 (2 8 - 1)).
Quando si utilizza l' waitid()API (o un gestore del segnale su SIGCHLD), sulla maggior parte dei sistemi (e come POSIX ora richiede più chiaramente nell'edizione 2016 dello standard (vedere le _exit()specifiche )), è disponibile il numero completo (nel si_statuscampo della struttura restituita ). Questo non è ancora il caso su Linux, che comunque tronca il numero a 8 bit con l' waitid()API, anche se è probabile che cambi in futuro.
In generale, si desidera utilizzare solo i valori da 0 (che in genere significano successo) a 125, poiché molte shell usano valori superiori a 128 nella loro $?rappresentazione dello stato di uscita per codificare il numero di segnale di un processo che viene ucciso e 126 e 127 per speciali condizioni.
Potresti voler usare 126 a 255 exit()per significare la stessa cosa che fanno per la shell $?(come quando fa uno script ret=$?; ...; exit "$ret"). L'uso di valori al di fuori di 0 -> 255 non è generalmente utile. Generalmente lo faresti solo se sai che il genitore utilizzerà l' waitid()API su sistemi che non si troncano e hai bisogno dell'intervallo di valori a 32 bit. Nota che se fai un exit(2048)esempio, questo sarà visto come un successo dai genitori usando il tradizionalewait*() API .
Maggiori informazioni su:
Speriamo che le domande e risposte rispondano alla maggior parte delle altre domande e chiariscano cosa si intende per stato di uscita . Aggiungerò alcune altre cose:
Un processo non può terminare a meno che non venga ucciso o non chiami le chiamate _exit()/ exit_group()system. Quando torni da main()dentroC , libc chiama quella chiamata di sistema con il valore restituito.
La maggior parte delle lingue ha una exit()funzione che avvolge quella chiamata di sistema e il valore che assumono, se ne viene generalmente passato uno qualsiasi alla chiamata di sistema. (nota che quelli generalmente fanno più cose come il clean-up fatto dalla exit()funzione di C che scarica i buffer dello stdio, esegue i atexit()ganci ...)
Questo è il caso di almeno:
$ 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)
Di tanto in tanto vedi alcuni che si lamentano quando usi un valore esterno a 0-255:
$ echo 'm4exit(1234)' | strace -e exit_group m4
m4:stdin:1: exit status out of range: `1234'
exit_group(1) = ?
Alcune shell si lamentano quando si utilizza un valore negativo:
$ 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 lascia il comportamento indefinito se il valore passato al exitbuiltin speciale è esterno a 0-> 255.
Alcune shell mostrano alcuni comportamenti imprevisti se lo fai:
bash(e mkshnon pdkshsu cui si basa) si assume il compito di troncare il valore a 8 bit:
$ strace -e exit_group bash -c 'exit 1234'
exit_group(210) = ?
Quindi in quelle shell, se vuoi uscire con un valore esterno a 0-255, devi fare qualcosa del tipo:
exec zsh -c 'exit -- -12345'
exec perl -e 'exit(-12345)'
Cioè eseguire un altro comando nello stesso processo che può chiamare la chiamata di sistema con il valore desiderato.
come menzionato in quell'altra ksh93domanda e risposta , ha il comportamento più strano per i valori di uscita da 257 a 256 + max_signal_number dove invece di chiamare exit_group()si uccide con il segnale corrispondente¹.
$ ksh -c 'exit "$((256 + $(kill -l STOP)))"'
zsh: suspended (signal) ksh -c 'exit "$((256 + $(kill -l STOP)))"'
e altrimenti tronca il numero come bash/ mksh.
¹ Questo probabilmente cambierà nella prossima versione. Ora che lo sviluppo di ksh93è stato assunto come uno sforzo della comunità al di fuori di AT&T, quel comportamento, sebbene incoraggiato in qualche modo da POSIX, è stato ripristinato
return.