Comment obtenir la liste des codes de sortie (et / ou des codes retour) et la signification d'une commande / d'un utilitaire?

17

Existe-t-il un moyen de faire ce qui est indiqué dans le titre à partir des commandes du terminal, ou vais-je devoir examiner les codes?

précis
la source

Réponses:

15

Il n'y a pas de "recette" pour obtenir la signification d'un état de sortie d'une commande de terminal donnée.

Ma première tentative serait la page de manuel:

user@host:~# man ls 
   Exit status:
       0      if OK,

       1      if minor problems (e.g., cannot access subdirectory),

       2      if serious trouble (e.g., cannot access command-line argument).

Deuxièmement : Google . Voir wget comme exemple.

Troisièmement : les états de sortie du shell, par exemple bash. Bash et ses fonctions intégrées peuvent utiliser des valeurs supérieures à 125 spécialement. 127 pour la commande introuvable, 126 pour la commande non exécutable. Pour plus d'informations, consultez les codes de sortie bash .

le chaos
la source
ouais un homme, info, ... les pages les incluent .. et je m'inquiétais pour ceux qui ne le faisaient pas. ..et je sais qu'une recherche sur le Web est toujours une option. .. comme pour l'instant il semble que ce soit juste les codes de sortie bash que je devais chercher ..
précis
12

Les codes de sortie indiquent une condition d'échec à la fin d'un programme et ils se situent entre 0 et 255. Le shell et ses commandes internes peuvent utiliser en particulier les valeurs supérieures à 125 pour indiquer des modes de défaillance spécifiques, donc la liste des codes peut varier entre les shells et les systèmes d'exploitation (par exemple Bash utilise la valeur 128 + N comme état de sortie). Voir: Bash - 3.7.5 Exit Status ou man bash.

En général, un état de sortie zéro indique qu'une commande a réussi , un état de sortie différent de zéro indique un échec .

Pour vérifier quel code d'erreur est retourné par la commande, vous pouvez imprimer $?pour le dernier code de sortie ou ${PIPESTATUS[@]}qui donne une liste des valeurs d'état de sortie du pipeline (dans Bash) après la fermeture d'un script shell.

Il n'y a pas de liste complète de tous les codes de sortie qui peuvent être trouvés, mais il y a eu une tentative de systématiser les numéros de statut de sortie dans la source du noyau, mais c'est principalement destiné aux programmeurs C / C ++ et une norme similaire pour les scripts pourrait être appropriée.

Une liste de sysexits sur Linux et BSD / OS X avec des codes de sortie préférables pour les programmes (64-78) peut être trouvée dans /usr/include/sysexits.h(ou: man sysexitssur BSD):

0   /* successful termination */
64  /* base value for error messages */
64  /* command line usage error */
65  /* data format error */
66  /* cannot open input */
67  /* addressee unknown */
68  /* host name unknown */
69  /* service unavailable */
70  /* internal software error */
71  /* system error (e.g., can't fork) */
72  /* critical OS file missing */
73  /* can't create (user) output file */
74  /* input/output error */
75  /* temp failure; user is invited to retry */
76  /* remote error in protocol */
77  /* permission denied */
78  /* configuration error */
/* maximum listed value */

La liste ci-dessus attribue les codes de sortie précédemment inutilisés de 64 à 78. La gamme de codes de sortie non attribués sera encore limitée à l'avenir.

Cependant, les valeurs ci-dessus sont principalement utilisées dans sendmail et utilisées par à peu près personne d'autre, elles ne sont donc pas à distance proches d'un standard (comme indiqué par @Gilles ).

Dans le shell, l'état de sortie est le suivant (basé sur Bash):

  • 1- 125- La commande ne s'est pas terminée avec succès. Consultez la page de manuel de la commande pour connaître la signification de l'état, quelques exemples ci-dessous:

  • 1 - Catchall pour les erreurs générales

    Erreurs diverses, telles que "diviser par zéro" et autres opérations non autorisées.

    Exemple:

    $ let "var1 = 1/0"; echo $?
    -bash: let: var1 = 1/0: division by 0 (error token is "0")
    1
    
  • 2 - Utilisation abusive des commandes internes de shell (selon la documentation de Bash)

    Mot-clé ou commande manquant, ou problème d'autorisation (et code de retour diff lors d'une comparaison de fichier binaire ayant échoué).

    Exemple:

     empty_function() {}
    
  • 6 - Aucun appareil ou adresse

    Exemple:

    $ curl foo; echo $?
    curl: (6) Could not resolve host: foo
    6
    
  • 124 - la commande expire

  • 125- si une commande elle-même échoue, voir: coreutils
  • 126 - si la commande est trouvée mais ne peut pas être invoquée (par exemple n'est pas exécutable)

    Le problème d'autorisation ou la commande n'est pas un exécutable.

    Exemple:

    $ /dev/null
    $ /etc/hosts; echo $?
    -bash: /etc/hosts: Permission denied
    126
    
  • 127 - si une commande est introuvable, le processus enfant créé pour l'exécuter renvoie cet état

    Problème possible avec $PATHou faute de frappe.

    Exemple:

    $ foo; echo $?
    -bash: foo: command not found
    127
    
  • 128 - Argument non valide pour exit

    exit ne prend que des arguments entiers compris entre 0 et 255.

    Exemple:

    $ exit 3.14159
    -bash: exit: 3.14159: numeric argument required
    
  • 128- 254- signal d'erreur fatale "n" - la commande est morte suite à la réception d'un signal. Le code du signal est ajouté à 128 (128 + SIGNAL) pour obtenir le statut (Linux man 7 signal:, BSD:) man signal, quelques exemples ci-dessous:

  • 130 - commande terminée en raison de la pression sur Ctrl-C, 130-128 = 2 (SIGINT)

    Exemple:

    $ cat
    ^C
    $ echo $?
    130
    
  • 137- si la commande est envoyée le KILL(9)signal (128 + 9), l'état de sortie de la commande sinon

    kill -9 $PPID du script.

  • 141- SIGPIPE- écrire sur une pipe sans lecteur

    Exemple:

    $ hexdump -n100000 /dev/urandom | tee &>/dev/null >(cat > file1.txt) >(cat > file2.txt) >(cat > file3.txt) >(cat > file4.txt) >(cat > file5.txt)
    $ find . -name '*.txt' -print0 | xargs -r0 cat | tee &>/dev/null >(head /dev/stdin > head.out) >(tail /dev/stdin > tail.out)
    xargs: cat: terminated by signal 13
    $ echo ${PIPESTATUS[@]}
    0 125 141
    
  • 143 - commande terminée par le code de signal 15 (128 + 15 = 143)

    Exemple:

    $ sleep 5 && killall sleep &
    [1] 19891
    $ sleep 100; echo $?
    Terminated: 15
    143
    
  • 255* - statut de sortie hors plage.

    exit ne prend que des arguments entiers compris entre 0 et 255.

    Exemple:

    $ sh -c 'exit 3.14159'; echo $?
    sh: line 0: exit: 3.14159: numeric argument required
    255
    

Selon le tableau ci-dessus, les codes de sortie 1 - 2, 126 - 165 et 255 ont des significations spéciales et doivent donc être évités pour les paramètres de sortie spécifiés par l'utilisateur.

Veuillez noter que les valeurs de sortie hors limites peuvent entraîner des codes de sortie inattendus (par exemple, la sortie 3809 donne un code de sortie de 225, 3809% 256 = 225).

Voir:

Kenorb
la source
errnoLes valeurs sont utilisées par les API système, elles ne sont pas utilisées comme états de sortie (elles ne sont même pas dans la bonne plage) et elles ne sont pas pertinentes pour les scripts shell. Les valeurs des sysexits proviennent de sendmail et sont utilisées par quasiment personne d'autre, elles ne sont pas du tout proches d'un standard.
Gilles 'SO- arrête d'être méchant'
7

Vous devrez examiner le code / la documentation. Cependant, la chose qui se rapproche le plus d'une "standardisation" est errno.h

Thorsten Staerk
la source
merci d'avoir pointé le fichier d'en-tête .. essayé de regarder dans la documentation de quelques utils .. difficile de trouver les codes de sortie, semble-t-il le plus sera les stderrs ...
précis
3
errno.hn'est pas pertinent pour les codes de sortie, seuls les messages d'erreur.
Gilles 'SO- arrête d'être méchant'
La plupart des programmes renvoient des codes de sortie conformément à la convention BSD, comme indiqué dans sysexits.h. Cependant, certains programmes renvoient des errnos, et je pense que retourner des errnos est le plus logique. Les errnos non gérés se propagent vers le haut, comme les exceptions, (les errnoséjours, les fonctions renvoient par exemple, -1ou 0|NULL). Étant donné que les programmes ne sont que des fonctions, bien que des fonctions exécutées dans un espace d'adressage distinct, il est logique qu'un programme souhaite continuer la errnopropagation à travers la frontière du processus.
PSkocik
@PSkocik, avez-vous un exemple d'une telle commande? les errnos ne sont pas portables (les valeurs ne sont pas cohérentes entre les systèmes), et il n'y a pas de moyen portable pour obtenir le nom ou le message d'erreur à partir de la valeur (zsh a une fonction intégrée pour cela). Sans oublier que certains systèmes ont des errnos au-dessus de 123 qui se heurteraient aux codes d'erreur à signification spéciale communs . Habituellement, les commandes impriment les messages de l'errno et renvoient un état de sortie de réussite / échec. les commandes sont destinées aux utilisateurs. les fonctions / appels système sont destinés aux programmeurs.
Stéphane Chazelas
@ StéphaneChazelas Je l'ai vu plusieurs fois, mais pas dans des programmes bien établis, je dois l'admettre. J'ai retourné personnellement errno + 1 dans mon système de jouets récemment (de sorte que 1 continue à signifier "toute erreur") parce que je pense que la sérialisation des erreurs à travers la frontière du processus est plus logique que de traduire selon la convention BSD, car les exécutions de programme sont essentiellement des invocations de fonctions, et les fonctions utilisent errno. J'utilise mon propre décodeur de dernier état de sortie dans mon PROMPT_COMMAND (bash) donc j'obtiens quelque chose comme "($numeric_code|$bsd_decoded|$errno_plus_one_decoded)".
PSkocik
1

Pour autant que je sache, il n'y a que deux valeurs standard, plus ou moins, toutes deux définies stdlib.hpour une utilisation avec exit ():

  • EXIT_SUCCESS (= 0)
  • EXIT_FAILURE (= 1)

Et la seule valeur standard de facto, c'est-à-dire ayant la même signification pour tous les programmes dans le monde, est 0 (zéro) qui signifie SUCCÈS.

Différents programmes introduisent différentes listes de codes "d'échec" renvoyés pour distinguer ou souligner différentes erreurs (différents types ou gravité). Certains programmes utilisent même la valeur renvoyée pour signaler le nombre entier d'erreurs d'exécution découvertes (par exemple, le nombre de tests unitaires ayant échoué dans la combinaison).

Je ne recommanderais pas d’introduire une quelconque "nouvelle norme" étendant la stdlib.h

xoiss
la source