'1' :fourre-tout pour les erreurs générales
'2' :Mauvaise utilisation des commandes internes du shell (selon la documentation de Bash)
'126' :La commande invoquée ne peut pas s'exécuter
'127' :"commande introuvable"
'128' :Argument invalide pour quitter
'128+n' :Signal d'erreur fatale "n"
'130' :Script terminé par Ctrl + C
'255' :Statut de sortie hors limites
C'est pour Bash. Cependant, pour d'autres applications, il existe différents codes de sortie.
Partie 1 : Guide de création de scripts avancés pour Bash
Comme toujours, le Advanced Bash Scripting Guide contient d'excellentes informations :(Ceci était lié dans une autre réponse, mais à une URL non canonique.)
1 : Catchall pour les erreurs générales
2 : Mauvaise utilisation des commandes intégrées du shell (selon la documentation de Bash)
126 : La commande invoquée ne peut pas s'exécuter
127 : "commande non trouvée"
128 : Argument invalide pour quitter
128+n : Signal d'erreur fatale "n"
255 : Statut de sortie hors plage (la sortie ne prend que des arguments entiers compris entre 0 et 255)
Partie 2 :sysexits.h
L'ABSG référence sysexits.h
.
Sous Linux :
$ find /usr -name sysexits.h
/usr/include/sysexits.h
$ cat /usr/include/sysexits.h
/*
* Copyright (c) 1987, 1993
* The Regents of the University of California. All rights reserved.
(A whole bunch of text left out.)
#define EX_OK 0 /* successful termination */
#define EX__BASE 64 /* base value for error messages */
#define EX_USAGE 64 /* command line usage error */
#define EX_DATAERR 65 /* data format error */
#define EX_NOINPUT 66 /* cannot open input */
#define EX_NOUSER 67 /* addressee unknown */
#define EX_NOHOST 68 /* host name unknown */
#define EX_UNAVAILABLE 69 /* service unavailable */
#define EX_SOFTWARE 70 /* internal software error */
#define EX_OSERR 71 /* system error (e.g., can't fork) */
#define EX_OSFILE 72 /* critical OS file missing */
#define EX_CANTCREAT 73 /* can't create (user) output file */
#define EX_IOERR 74 /* input/output error */
#define EX_TEMPFAIL 75 /* temp failure; user is invited to retry */
#define EX_PROTOCOL 76 /* remote error in protocol */
#define EX_NOPERM 77 /* permission denied */
#define EX_CONFIG 78 /* configuration error */
#define EX__MAX 78 /* maximum listed value */
8 bits du code de retour et 8 bits du numéro du signal de mise à mort sont mélangés en une seule valeur au retour de wait(2)
&co..
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <signal.h>
int main() {
int status;
pid_t child = fork();
if (child <= 0)
exit(42);
waitpid(child, &status, 0);
if (WIFEXITED(status))
printf("first child exited with %u\n", WEXITSTATUS(status));
/* prints: "first child exited with 42" */
child = fork();
if (child <= 0)
kill(getpid(), SIGSEGV);
waitpid(child, &status, 0);
if (WIFSIGNALED(status))
printf("second child died with %u\n", WTERMSIG(status));
/* prints: "second child died with 11" */
}
Comment déterminez-vous le statut de sortie ? Traditionnellement, le shell ne stocke qu'un code de retour de 8 bits, mais définit le bit haut si le processus s'est terminé de manière anormale.
$ sh -c 'exit 42'; echo $? 42 $ sh -c 'kill -SEGV $$'; echo $? Segmentation fault 139 $ expr 139 - 128 11
Si vous voyez autre chose que cela, le programme a probablement un SIGSEGV
gestionnaire de signal qui appelle ensuite exit
normalement, il n'est donc pas réellement tué par le signal. (Les programmes peuvent choisir de gérer tous les signaux en dehors de SIGKILL
et SIGSTOP
.)
Aucune des réponses les plus anciennes ne décrit correctement le statut de sortie 2. Contrairement à ce qu'ils prétendent, l'état 2 est ce que vos utilitaires de ligne de commande renvoient réellement lorsqu'ils sont appelés de manière incorrecte. (Oui, une réponse peut avoir neuf ans, avoir des centaines de votes positifs et toujours se tromper.)
Voici la véritable convention de statut de sortie de longue date pour une terminaison normale, c'est-à-dire pas par signal :
- État de sortie 0 :succès
- État de sortie 1 :"échec", tel que défini par le programme
- État de sortie 2 :erreur d'utilisation de la ligne de commande
Par exemple, diff
renvoie 0 si les fichiers qu'il compare sont identiques, et 1 s'ils diffèrent. Par convention de longue date, les programmes Unix renvoient l'état de sortie 2 lorsqu'ils sont appelés de manière incorrecte (options inconnues, nombre d'arguments erroné, etc.) Par exemple, diff -N
, grep -Y
ou diff a b c
aboutiront tous à $?
étant défini sur 2. C'est et c'est la pratique depuis les débuts d'Unix dans les années 1970.
La réponse acceptée explique ce qui se passe lorsqu'une commande est terminée par un signal. En bref, l'arrêt dû à un signal non capté entraîne le statut de sortie 128+[<signal number>
. Par exemple, résiliation par SIGINT
(signal 2) entraîne l'état de sortie 130.
Remarques
-
Plusieurs réponses définissent le statut de sortie 2 comme "Mauvaise utilisation des fonctions intégrées bash". Cela s'applique uniquement lorsque bash (ou un script bash) se termine avec le statut 2. Considérez cela comme un cas particulier d'erreur d'utilisation incorrecte.
-
En
sysexits.h
, mentionné dans la réponse la plus populaire, état de sortieEX_USAGE
("erreur d'utilisation de la ligne de commande") est définie comme étant 64. Mais cela ne reflète pas la réalité :je n'en connais aucune utilitaire Unix courant qui renvoie 64 en cas d'invocation incorrecte (exemples bienvenus). Une lecture attentive du code source révèle quesysexits.h
est une aspiration plutôt qu'un reflet de l'utilisation réelle :* This include file attempts to categorize possible error * exit statuses for system programs, notably delivermail * and the Berkeley network. * Error numbers begin at EX__BASE [64] to reduce the possibility of * clashing with other exit statuses that random programs may * already return.
En d'autres termes, ces définitions ne reflètent pas la pratique courante à l'époque (1993) mais étaient intentionnellement incompatibles avec celle-ci. Plus c'est dommage.