Existe-t-il des codes d'état de sortie standard dans Linux?
Un processus est considéré comme terminé correctement sous Linux si son état de sortie était 0.
J'ai vu que les défauts de segmentation entraînent souvent un statut de sortie de 11, bien que je ne sache pas si c'est simplement la convention où je travaille (les applications qui ont échoué comme ça ont toutes été internes) ou une norme.
Existe-t-il des codes de sortie standard pour les processus sous Linux?
10 réponses
8 bits du code de retour et 8 bits du nombre 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 élevé si le processus a été anormalement terminé.
$ 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, alors le programme a probablement un gestionnaire de signal SIGSEGV
qui appelle alors exit
normalement, donc ce n'est pas le cas en fait se faire tuer par le signal. (Les programmes peuvent choisir de gérer tous les signaux en dehors de SIGKILL
et SIGSTOP
.)
Partie 1: Guide De Script Bash Avancé
Comme toujours, la Advanced Bash Scripting Guide a grande information: (Ceci a été lié dans une autre réponse, mais à une URL non canonique.)
1: Catchall pour les erreurs générales
2: utilisation abusive de shell builtins (selon la documentation Bash)
126: la commande appelée ne peut pas s'exécuter
127: "commande non trouvée"
128: Argument non valide pour sortie
128+n: signal d'erreur Fatale "n"
255: statut de Sortie hors de portée (la sortie ne prend que entier args dans la gamme de 0 à 255)
Partie 2: sysexits.h
Les références ABSG 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 */
'1' >>> fourre-tout pour les erreurs générales
'2' >>> utilisation abusive de shell builtins (selon la documentation Bash)
'126'>>> la commande appelée ne peut pas exécuter
'127'>>>"Commande non trouvée"
'128'>>> argument non valable pour la sortie
'128+n'>>>signal d'erreur Fatale "n"
'130'>>> Script résilié par le Contrôle de C-
'255'>>>État de sortie hors de portée
Ce est pour bash. Cependant, pour d'autres applications, il existe différents codes de sortie.
Aucune des réponses plus anciennes ne décrit correctement l'état de sortie 2. Contrairement à ce qu'ils prétendent, status 2 est ce que vos utilitaires de ligne de commande renvoient réellement lorsqu'ils sont appelés incorrectement. (Oui, une réponse peut avoir neuf ans, avoir des centaines de votes positifs, et toujours avoir tort.)
Voici la vraie convention d'état de sortie de longue date pour la terminaison normale, c'est-à-dire pas par signal:
- État de sortie 0: succès
- État de sortie 1: "Échec", tel que défini par programme
- État de sortie 2: Erreur d'utilisation de la ligne de commande
Par exemple diff
retourne 0 si les fichiers qu'il compare sont identiques, et 1 si elles diffèrent. Par convention de longue date, les programmes unix renvoient exit status 2 lorsqu'ils sont appelés incorrectement (options inconnues, nombre d'arguments erronés, etc.), Par exemple, diff -N
, grep -Y
ou diff a b c
tous les résultats dans $?
étant fixé à 2. C'Est et a été la pratique depuis les premiers jours D'Unix dans les années 1970.
Le réponse acceptée explique ce qui se passe lorsqu'une commande est terminée par par un signal. en bref, la terminaison due à un signal non intercepté entraîne l'état de sortie 128+[<signal number>
. Par exemple, résiliation par SIGINT
(signal 2 ) donne l'état de sortie 130.
Notes
Plusieurs réponses définissent exit status 2 comme "mauvaise utilisation des builtins bash". Cela s'applique uniquement lorsque bash (ou un script bash) se termine avec le statut 2. Considérez - le comme un cas particulier de erreur d'utilisation incorrecte.
-
Dans
sysexits.h
, mentionné dans le plus populaires réponse, statut de sortieEX_USAGE
("ligne de commande erreur d'utilisation") est défini pour être 64. Mais cela ne reflète pas la réalité: Je ne suis pas au courant de Tout utilitaire Unix commun qui renvoie 64 en cas d'invocation incorrecte (exemples bienvenus). Une lecture attentive du code source révèle quesysexits.h
est ambitieux, plutôt que le reflet d'un véritable usage:* 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.
Dans autrement dit, ces définitions ne reflètent pas la pratique courante à l'époque (1993), mais étaient intentionnellement incompatibles avec celle-ci. Plus de la pitié.
Il n'y a pas de codes de sortie standard, à part 0 qui signifie succès. Non-zéro ne signifie pas nécessairement l'échec non plus.
Stdlib.h définit EXIT_FAILURE
comme 1 et {[1] } comme 0, mais c'est à peu près tout.
Le 11 sur segfault est intéressant, car 11 est le numéro de signal que le noyau utilise pour tuer le processus en cas de segfault. Il y a probablement un mécanisme, dans le noyau ou dans le shell, qui traduit cela dans le code de sortie.
Sysexits.h est une liste des codes de sortie. Il semble remonter à au moins 1993 et certains grands projets comme Postfix l'utilisent, donc j'imagine que c'est la voie à suivre.
Depuis la page de manuel OpenBSD:
Selon style (9), Il n'est pas recommandé d'appeler exit (3) avec arbi- trary valeurs pour indiquer une condition d'échec lors de la fin d'un programme. Dans- au lieu de cela, les codes de sortie prédéfinis de sysexits doivent être utilisés, de sorte que le l'appelant peut obtenir une estimation approximative à propos de l'échec de la classe sans chercher le code source.
À une première approximation, 0 est un succès, non nul est un échec, 1 étant un échec général, et tout ce qui est plus grand que l'un étant un échec spécifique. Mis à part les exceptions triviales de false et test, qui sont toutes deux conçues pour donner 1 pour le succès, il y a quelques autres exceptions que j'ai trouvées.
Plus réaliste, 0 signifie succès ou peut-être échec, 1 signifie échec général ou peut-être succès, 2 signifie échec général si 1 et 0 sont tous deux utilisés pour succès, mais peut-être aussi succès.
La commande diff donne 0 si les fichiers comparés sont identiques, 1 s'ils diffèrent et 2 si les binaires sont différents. 2 signifie également échec. La commande less donne 1 pour échec sauf si vous ne parvenez pas à fournir un argument, auquel cas, il quitte 0 malgré l'échec.
La commande more et la commande spell donnent 1 pour échec, sauf si l'échec est le résultat d'une autorisation refusée, d'un fichier inexistant ou d'une tentative de lecture d'un répertoire. Dans tous ces cas, ils sortent 0 malgré défaillant.
Alors la commande expr donne 1 pour sucess sauf si la sortie est la chaîne vide ou zéro, auquel cas, 0 est sucess. 2 et 3 sont des échecs.
Ensuite, il y a des cas où le succès ou l'échec est ambigu. Lorsque grep ne parvient pas à trouver un motif, il quitte 1, mais il quitte 2 pour un véritable échec (comme l'Autorisation refusée). Klist quitte également 1 quand il ne parvient pas à trouver un ticket, bien que ce ne soit pas vraiment plus un échec que lorsque grep ne trouve pas de modèle, ou lorsque vous êtes un répertoire vide.
Donc, malheureusement, les pouvoirs unix qui sont ne semblent pas appliquer un ensemble logique de règles, même sur les exécutables très couramment utilisés.
Les programmes renvoient un code de sortie de 16 bits. Si le programme a été tué avec un signal, alors l'octet d'ordre Élevé contient le signal utilisé, sinon l'octet d'ordre bas est l'état de sortie retourné par le programmeur.
Comment ce code de sortie est affecté à la variable d'état $? est puis vers le haut de la coquille. Bash conserve les 7 bits inférieurs de l'état, puis utilise 128 + (signal nr) pour indiquer un signal.
La seule convention "standard" pour les programmes est 0 pour le succès, non-zéro pour l'erreur. Une autre convention utilisée est de renvoyer errno en cas d'erreur.
Les codes de sortie Unix Standard sont définis par sysexits.h, comme une autre affiche mentionné. Les mêmes codes de sortie sont utilisés par les bibliothèques portables telles que Poco-en voici une liste:
Http://pocoproject.org/docs/Poco.Util.Application.html#16218
Un signal 11 est un signal SIGSEGV (violation de segment), qui est différent d'un code de retour. Ce signal est généré par le noyau en réponse à un mauvais accès à la page, ce qui provoque la fin du programme. Une liste de signaux se trouve dans la page de manuel du signal (exécutez "Man signal").
Lorsque Linux renvoie 0, cela signifie succès. Toute autre chose signifie l'échec, chaque programme a ses propres codes de sortie, il serait donc assez long de les énumérer tous... !
A propos du code d'erreur 11, c'est en effet le numéro de défaut de segmentation, ce qui signifie principalement que le programme a accédé à un emplacement de mémoire qui n'a pas été attribué.