Risposte:
Questo è lo stato di uscita dell'ultimo comando eseguito.
Ad esempio il comando true
restituisce sempre uno stato di 0
e false
restituisce sempre uno stato di 1
:
true
echo $? # echoes 0
false
echo $? # echoes 1
Dal manuale: (accessibile chiamando man bash
la shell)
$?
Si espande allo stato di uscita della pipeline in primo piano eseguita più di recente.
Per convenzione, uno stato di uscita 0
significa successo e uno stato di ritorno diverso da zero significa fallimento. Ulteriori informazioni sugli stati di uscita su Wikipedia .
Esistono altre variabili speciali come questa, come puoi vedere in questo manuale online: https://www.gnu.org/s/bash/manual/bash.html#Special-Parameters
$
e ?
sono due parametri distinti e $?
non appare nella manpage bash (1).
$?
restituisce il valore di uscita dell'ultimo comando eseguito. echo $?
stampa quel valore sulla console. zero implica un'esecuzione corretta mentre i valori diversi da zero sono associati a vari motivi di errore.
Quindi quando lo scripting; Tendo a usare la sintassi seguente
if [ $? -eq 0 ]; then
# do something
else
# do something else
fi
Il confronto deve essere fatto su uguale 0
o meno uguale 0
.
** Aggiornamento basato sul commento: idealmente, non si dovrebbe usare il blocco di codice sopra per il confronto, fare riferimento ai commenti e alla spiegazione di @tripleee.
cmd; if [ $? -eq 0 ]; then
dovrebbe essere rifattorizzato if cmd; then
. Lo scopo stesso di if
(e delle altre istruzioni di controllo del flusso nella shell) è eseguire un comando ed esaminarne lo stato di uscita.
if cmd;
potrebbe non essere molto leggibile è alcune condizioni soprattutto quando cmd si riferisce a un altro script.
[ 1 ]
e [ 0 ]
sono entrambi veri; [
senza un operatore controlla se l'argomento è una stringa non vuota.
vendor/bin/drush status bootstrap | grep -q $(vendor/bin/drush php-eval 'if (function_exists("t")) echo t("Successful");') &> /dev/null;
. Se dovessi metterlo in una sola riga if [ ... ]
sarebbe terribilmente illeggibile. Ho intenzione di archiviare l'output di quella riga in una variabile in modo da poterlo dire in if [ $drupal_installed -eq 0 ]
seguito.
echo $? - Fornisce lo STATO DI USCITA del comando eseguito più di recente . Questo STATO DI USCITA sarebbe probabilmente un numero con ZERO che implica Successo e qualsiasi valore NON-ZERO che indica Fallimento
? - Questo è un parametro / variabile speciale in bash.
$? - Fornisce il valore memorizzato nella variabile "?".
Alcuni parametri speciali simili in BASH sono 1,2, *, # (normalmente visti nel comando echo come $ 1, $ 2, $ *, $ #, ecc.).
Ha l'ultimo codice di stato (valore di uscita) di un comando.
Esempio di stato di uscita C POSIX minimo
Per capire $?
, devi prima capire il concetto di stato di uscita del processo che è definito da POSIX . In Linux:
quando un processo chiama la exit
chiamata di sistema, il kernel memorizza il valore passato alla chiamata di sistema (an int
) anche dopo la fine del processo.
La chiamata di sistema di uscita è chiamato dal exit()
funzione di ANSI C, e, indirettamente, quando si fa return
da main
.
il processo che ha chiamato il processo figlio uscente (Bash), spesso con fork
+ exec
, può recuperare lo stato di uscita del figlio con la wait
chiamata di sistema
Considera il codice Bash:
$ false
$ echo $?
1
"C" equivalente è:
false.c
#include <stdlib.h> /* exit */
int main(void) {
exit(1);
}
bash.c
#include <unistd.h> /* execl */
#include <stdlib.h> /* fork */
#include <sys/wait.h> /* wait, WEXITSTATUS */
#include <stdio.h> /* printf */
int main(void) {
if (fork() == 0) {
/* Call false. */
execl("./false", "./false", (char *)NULL);
}
int status;
/* Wait for a child to finish. */
wait(&status);
/* Status encodes multiple fields,
* we need WEXITSTATUS to get the exit status:
* http://stackoverflow.com/questions/3659616/returning-exit-code-from-child
**/
printf("$? = %d\n", WEXITSTATUS(status));
}
Compila ed esegui:
g++ -ggdb3 -O0 -std=c++11 -Wall -Wextra -pedantic -o bash bash.c
g++ -ggdb3 -O0 -std=c++11 -Wall -Wextra -pedantic -o false false.c
./bash
Produzione:
$? = 1
In Bash, quando premi Invio, un fork + exec + wait avviene come sopra, e bash quindi imposta $?
sullo stato di uscita del processo biforcato.
Nota: per comandi integrati come echo
, non è necessario generare un processo e Bash si limita $?
a 0 per simulare un processo esterno.
Standard e documentazione
POSIX 7 2.5.2 "Parametri speciali" http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_05_02 :
? Si espande allo stato di uscita decimale della pipeline più recente (consultare Pipeline).
man bash
"Parametri speciali":
La shell tratta diversi parametri appositamente. Questi parametri possono solo essere referenziati; l'assegnazione a loro non è consentita. [...]
? Si espande allo stato di uscita della pipeline in primo piano eseguita più di recente.
ANSI C e POSIX raccomandano quindi di:
0
significa che il programma ha avuto successo
altri valori: il programma è fallito in qualche modo.
Il valore esatto potrebbe indicare il tipo di errore.
ANSI C non definisce il significato di alcun valore e POSIX specifica valori maggiori di 125: Qual è il significato di "POSIX"?
Bash utilizza lo stato di uscita per if
In Bash, usiamo spesso $?
implicitamente lo stato di uscita per controllare le if
istruzioni come in:
if true; then
:
fi
dove true
è un programma che restituisce solo 0.
Quanto sopra equivale a:
true
result=$?
if [ $result = 0 ]; then
:
fi
E in:
if [ 1 = 1 ]; then
:
fi
[
è solo un programma con un nome strano (e incorporato in Bash che si comporta in modo simile), e i 1 = 1 ]
suoi argomenti, vedi anche: Differenza tra parentesi quadre singole e doppie in Bash
Da http://www.gnu.org/s/bash/manual/bash.html#Special-Parameters
?
Expands to the exit status of the most recently executed foreground pipeline.
Vedere il Manuale di Bash in 3.4.2 Parametri speciali :
? - Si espande allo stato di uscita dell'ultima pipeline in primo piano eseguita.
È un po 'difficile da trovare perché non è elencato come $?
(il nome della variabile è "solo" ?
). Vedi anche la sezione sullo stato di uscita , ovviamente ;-)
Buona codifica.