J'essaie d'apprendre les scripts Shell et j'ai besoin de comprendre le code de quelqu'un d'autre. Quelle est la valeur de la variable $?
? Je ne peux pas rechercher la réponse sur Google car ils bloquent les caractères de ponctuation.
$?
est utilisé pour trouver la valeur de retour de la dernière commande exécutée. Essayez ce qui suit dans le shell:
ls somefile
echo $?
Si somefile
existe (que ce soit un fichier ou un répertoire), vous obtiendrez la valeur renvoyée par la commande ls
, qui devrait être 0
(valeur renvoyée par défaut "success") . S'il n'existe pas, vous devriez obtenir un nombre autre que 0. Le nombre exact dépend du programme.
Pour de nombreux programmes, vous pouvez trouver les numéros et leur signification dans la page de manuel correspondante. Celles-ci seront généralement décrites comme "statut de sortie" et peuvent avoir leur propre section.
C'est l'état de sortie de la dernière fonction/programme/commande exécutée. Faire référence à:
Une valeur de retour du processus précédemment exécuté.
10.4 Obtenir la valeur de retour d'un programme
Dans bash, la valeur de retour d'un programme est stockée dans une variable spéciale appelée $ ?.
Ceci illustre comment capturer la valeur de retour d'un programme, je suppose que le répertoire dada n'existe pas. (Cela a également été suggéré par Mike)
#!/bin/bash cd /dada &> /dev/null echo rv: $? cd $(pwd) &> /dev/null echo rv: $?
Voir Manuel de programmation Bash pour plus de détails.
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
où 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
$? est le résultat (code de sortie) de la dernière commande exécutée.
$?
est le statut de sortie d'une commande, de sorte que vous pouvez chaîner une série de commandes.
Exemple
command1 && command2 && command3
command2
s'exécutera si command1's
$?
donne un success (0)
et command3
s'exécutera si $?
de command2
donnera un success
C'est le code d'erreur renvoyé de la dernière commande exécutée. 0 = succès
Il convient bien au débogage dans le cas où votre script se termine si set -e
est utilisé. Par exemple, mettez echo $?
après la commande qui provoque sa fermeture et consultez la valeur d'erreur renvoyée.
Le code de sortie de la dernière commande a été exécuté.