web-dev-qa-db-fra.com

Signification de $? (point d'interrogation dollar) dans les scripts Shell

Qu'est-ce que

echo $?

signifie dans la programmation Shell?

138
Harshay Buradkar

C'est l'état de sortie de la dernière commande exécutée.

Par exemple, la commande true renvoie toujours un statut de 0 et false renvoie toujours un statut de 1:

true
echo $? # echoes 0
false
echo $? # echoes 1

Extrait du manuel: (accessible en appelant man bash dans votre shell)

$? Étend le statut de sortie du pipeline de premier plan exécuté le plus récemment.

Par convention, un état de sortie de 0 signifie succès, et un état de retour non nul signifie échec. En savoir plus sur les statuts de sortie sur wikipedia .

Il existe d'autres variables spéciales comme celle-ci, comme vous pouvez le constater sur ce manuel en ligne: https://www.gnu.org/s/bash/manual/bash.html#Special-Parameters

165
Arnaud Le Blanc

$? renvoie la valeur de sortie de la dernière commande exécutée. echo $? imprime cette valeur sur la console. zéro implique une exécution réussie alors que des valeurs non nulles sont mappées sur différentes raisons d'échec.

D'où lors de l'écriture du script; J'ai tendance à utiliser la syntaxe suivante

if [ $? -eq 0 ]; then
 # do something
else
 # do something else
fi

La comparaison doit être effectuée sur un nombre égal à 0 ou non égal à 0.

** Mise à jour Sur la base du commentaire: Idéalement, vous ne devez pas utiliser le bloc de code ci-dessus à des fins de comparaison. Reportez-vous aux commentaires et aux explications de @tripleee.

16
Saurabh Ariyan

echo $? - Donne le statut EXIT STATUS de la commande la plus récemment exécutée . Cet état de sortie serait très probablement un nombre avec ZERO impliquant Success et toute valeur NON-ZERO indiquant Failure

? - Ceci est un paramètre/variable spécial en bash.

$? - Il donne la valeur stockée dans la variable "?".

Certains paramètres spéciaux similaires dans BASH sont 1,2, *, # (normalement visibles dans la commande echo sous la forme $ 1, $ 2, $ *, $ #, etc.).

6
Arun Karthik

Il a le dernier code d'état (valeur de sortie) d'une commande.

6
Ned Batchelder

De http://www.gnu.org/s/bash/manual/bash.html#Special-Parameters

?
Expands to the exit status of the most recently executed foreground pipeline. 
2
evil otto

Affiche le résultat de la dernière commande unix exécutée

0 implies true
1 implies false
1
Sojourner

Exemple d'état de sortie minimal pour POSIX C

Pour comprendre $?, vous devez d'abord comprendre le concept d'état de sortie du processus.

Sous Linux:

  • lorsqu'un processus appelle l'appel système exit, le noyau stocke la valeur transmise à l'appel système même après la mort du processus.

    L'appel système de sortie est appelé par la fonction exit() ANSI C, et indirectement lorsque vous effectuez return à partir de main.

  • le processus qui a appelé le processus enfant sortant (Bash), souvent avec fork + exec, peut récupérer l'état de sortie de l'enfant avec l'appel système wait

Considérons le code Bash:

$ false
$ echo $?
1

Le "équivalent" C est:

false.c:

#include <stdlib.h> /* exit */

int main() {
    exit(1);
}

bash.c:

#include <unistd.h> /* execl */
#include <stdlib.h> /* fork */
#include <sys/wait.h> /* wait, WEXITSTATUS */
#include <stdio.h> /* printf */

int main() {
    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));
}

Dans Bash, lorsque vous appuyez sur entrée, un fork + exec + wait se passe comme ci-dessus, puis bash définit ensuite $? sur le statut de sortie du processus fork.

Remarque: pour les commandes intégrées telles que echo, il n'est pas nécessaire de générer un processus et Bash configure simplement $? à 0 pour simuler un processus externe.

Normes et documentation

POSIX 7 2.5.2 "Paramètres spéciaux" http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_05_02 :

? Développe le statut de sortie décimal du pipeline le plus récent (voir Pipelines).

man bash "Paramètres spéciaux":

Le shell traite spécialement plusieurs paramètres. Ces paramètres ne peuvent être référencés que; leur assignation n'est pas autorisée. [...]

? Développe le statut de sortie du pipeline de premier plan exécuté le plus récemment.

ANSI C et POSIX recommandent alors que:

  • 0 signifie que le programme a réussi

  • autres valeurs: le programme a échoué en quelque sorte.

    La valeur exacte pourrait indiquer le type d'échec.

    ANSI C ne définit pas la signification des valeurs, et POSIX spécifie des valeurs supérieures à 125: Quelle est la signification de "POSIX"?

Bash utilise le statut de sortie pour if

Dans Bash, nous utilisons souvent le statut de sortie $? implicitement pour contrôler les instructions if comme dans:

if true; then
  :
fi

true est un programme qui ne retourne que 0.

Ce qui précède est équivalent à:

true
result=$?
if [ $result = 0 ]; then
  :
fi

Et en:

if [ 1 = 1 ]; then
  :
fi

[ est juste un programme avec un nom étrange (et Bash intégré qui se comporte de la sorte), et 1 = 1 ] ses arguments, voir aussi: Différence entre les crochets simples et doubles dans Bash

Voir The Bash Manual sous .4.2 Paramètres spéciaux :

? - Étend le statut de sortie du pipeline de premier plan exécuté le plus récemment.

C'est un peu difficile à trouver car il ne figure pas dans la liste sous le nom $? (le nom de la variable est "simplement" ?). Voir aussi la section statut de sortie , bien sûr ;-)

Bonne codage.

1
user166390