Quali sono i valori minimo e massimo dei seguenti codici di uscita in Linux:
- Il codice di uscita restituito da un eseguibile binario (ad esempio:un programma C
). - Il codice di uscita restituito da uno script bash (quando si chiama
exit
). - Il codice di uscita restituito da una funzione (quando si chiama
return
).
penso che sia trae
255
.
Risposta accettata:
Il numero passato a _exit()
/exit_group()
chiamata di sistema (a volte indicata come codice di uscita per evitare l'ambiguità con 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 terminato normalmente) è di tipo int
, quindi su sistemi simili a Unix come Linux, in genere un intero a 32 bit con valori compresi tra -2147483648 (-2) e 2147483647 (2-1).
Tuttavia, su tutti i sistemi, quando il processo padre (o il subreaper figlio o init
se il genitore è morto) usa wait()
, waitpid()
, wait3()
, wait4()
chiamate di sistema per recuperarlo, sono disponibili solo gli 8 bit inferiori (valori da 0 a 255 (2-1)).
Quando si utilizza waitid()
API (o un gestore di segnali su SIGCHLD), sulla maggior parte dei sistemi (e come POSIX ora richiede più chiaramente nell'edizione 2016 dello standard (vedi _exit()
specifica)), il numero completo è disponibile (in si_status
campo della struttura restituita). Questo non è ancora il caso su Linux, che tronca anche il numero a 8 bit con waitid()
API, anche se è probabile che cambi in futuro.
In genere, vorresti utilizzare solo i valori da 0 (generalmente significa successo) a 125, poiché molte shell usano valori superiori a 128 nel loro $?
rappresentazione dello stato di uscita per codificare il numero del segnale di un processo che viene ucciso e 126 e 127 per condizioni speciali.
Potresti voler usare da 126 a 255 su exit()
significano la stessa cosa che fanno per il $?
della shell (come quando uno script fa ret=$?; ...; exit "$ret"
). L'uso di valori al di fuori di 0 -> 255 non è generalmente utile. In genere lo faresti solo se sai che il genitore utilizzerà waitid()
API su sistemi che non troncano e ti capita di avere bisogno dell'intervallo di valori a 32 bit. Nota che se esegui un exit(2048)
per esempio, sarà visto come un successo dai genitori che usano il tradizionale wait*()
API.
Maggiori informazioni su:
- Codice di uscita predefinito al termine del processo?
Che le domande e risposte dovrebbero, si spera, rispondere alla maggior parte delle altre tue domande e chiarire cosa si intende per stato di uscita . Aggiungo ancora alcune cose:
Un processo non può terminare a meno che non venga terminato o non chiami _exit()
/exit_group()
chiamate di sistema. Quando torni da main()
in C
, la libc chiama quella chiamata di sistema con il valore restituito.
La maggior parte delle lingue ha un exit()
funzione che racchiude quella chiamata di sistema e il valore che assumono, se presente, viene generalmente passato così com'è alla chiamata di sistema. (nota che quelli generalmente fanno più cose come la pulizia fatta da exit()
di C funzione che svuota i buffer stdio, esegue atexit()
ganci…)
Questo è il caso almeno di:
$ 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 ne vedi alcuni che si lamentano quando utilizzi un valore al di fuori di 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 usi 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 a exit
lo speciale integrato è esterno a 0->255.
Alcune shell mostrano alcuni comportamenti imprevisti se lo fai:
-
bash
(emksh
ma nonpdksh
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 al di fuori di 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ò chiama la chiamata di sistema con il valore che desideri.
-
come menzionato in quell'altra domanda e risposta,
ksh93
ha il comportamento più strano per i valori di uscita da 257 a 256+max_signal_number dove invece di chiamareexit_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
.