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 init
se 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_status
campo 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 exit
builtin speciale è esterno a 0-> 255.
Alcune shell mostrano alcuni comportamenti imprevisti se lo fai:
bash
(e mksh
non pdksh
su 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 ksh93
domanda 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
.