GNU/Linux >> Tutoriels Linux >  >> Linux

Les codes de sortie de la ligne de commande Bash démystifiés

Lorsque vous exécutez une commande ou lancez un script, vous recevez un code de sortie . Un code de sortie est une réponse du système qui signale un succès, une erreur ou une autre condition qui fournit un indice sur la cause d'un résultat inattendu de votre commande ou de votre script. Pourtant, vous ne connaîtrez peut-être jamais le code, car un code de sortie ne se révèle pas à moins que quelqu'un ne lui demande de le faire. Les programmeurs utilisent des codes de sortie pour déboguer leur code.

Remarque : Vous verrez souvent un code de sortie appelé statut de sortie ou même comme codes d'état de sortie . Les termes sont utilisés de manière interchangeable, sauf dans la documentation. J'espère que mon utilisation des deux termes sera claire pour vous.

Je ne suis pas programmeur. C'est difficile pour moi de l'admettre, mais c'est vrai. J'ai étudié BASIC, FORTRAN et quelques autres langages à la fois formels et informels, et je dois dire que je ne suis certainement pas un programmeur. Oh, bien sûr, je peux écrire des scripts et programmer un peu en PHP, Perl, Bash et même PowerShell (oui, je suis aussi un administrateur Windows), mais je ne pourrais jamais gagner ma vie en programmation car je suis trop lent à écrire du code et les essais et erreurs ne sont pas une stratégie de débogage efficace. C'est triste, vraiment, mais je suis suffisamment compétent pour copier et adapter le code trouvé pour pouvoir accomplir les tâches requises. Et pourtant, j'utilise aussi des codes de sortie pour comprendre où sont mes problèmes et pourquoi les choses tournent mal.

[ Vous pourriez également aimer : Un peu de magie de copie de fichiers SSH sur la ligne de commande. ]

Les codes de sortie sont utiles dans une certaine mesure, mais ils peuvent aussi être vagues. Par exemple, un code de sortie de 1 est un compartiment générique pour les erreurs diverses et n'est pas du tout utile. Dans cet article, j'explique la poignée de codes d'erreur réservés , comment ils peuvent se produire et comment les utiliser pour déterminer quel est votre problème. Un code d'erreur réservé est celui qui est utilisé par Bash et vous ne devez pas créer vos propres codes d'erreur qui entrent en conflit avec eux.

Assez d'histoire. Il est temps de regarder des exemples de ce qui génère des codes/statuts d'erreur.

Extraire le code de sortie insaisissable

Pour afficher le code de sortie de la dernière commande que vous avez exécutée sur la ligne de commande, utilisez la commande suivante :

$ echo $?

La réponse affichée ne contient aucune pompe ou circonstance. Il s'agit simplement d'un nombre. Vous pouvez également recevoir un message d'erreur du shell de Bash décrivant plus en détail l'erreur, mais le code de sortie et l'erreur du shell devraient vous aider à découvrir ce qui n'a pas fonctionné.

État de sortie 0

Un état de sortie de 0 est le meilleur scénario possible, d'une manière générale. Il vous indique que votre dernière commande ou script s'est exécuté avec succès. Le succès est relatif car le code de sortie vous informe uniquement que le script ou la commande s'est bien exécuté, mais le code de sortie ne vous dit pas si les informations qu'il contient ont une valeur. Des exemples illustreront mieux ce que je décris.

Par exemple, répertoriez les fichiers de votre répertoire personnel. Je n'ai rien dans mon répertoire personnel autre que des fichiers et des répertoires cachés, donc rien à voir ici, mais le code de sortie ne se soucie de rien d'autre que du succès de l'exécution de la commande :

$ ls
$ echo $?
0

Le code de sortie de 0 signifie que le ls la commande s'est exécutée sans problème. Bien que, encore une fois, les informations du code de sortie ne me fournissent aucune valeur réelle.

Maintenant, exécutez le ls commande sur /etc répertoire puis affichez le code de sortie :

$ ls /etc
**Many files**
$ echo $?
0

Vous pouvez voir que toute exécution réussie entraîne un code de sortie de 0, y compris quelque chose qui est totalement faux, comme l'émission du cat commande sur un fichier exécutable binaire comme ls commande : 

$ cat /usr/bin/ls
**A lot of screen gibberish and beeping**
$ echo $?
0

État de sortie 1

En utilisant l'exemple ci-dessus mais en ajoutant la liste longue et les options récursives (-lR ), vous recevez un nouveau code de sortie de 1 :

$ ls -lR /etc
**A lengthy list of files**
$ echo $?
1

Bien que la sortie de la commande donne l'impression que tout s'est bien passé, si vous faites défiler vers le haut, vous verrez plusieurs erreurs "Autorisation refusée" dans la liste. Ces erreurs entraînent un état de sortie de 1, qui est décrit comme "opérations non autorisées". Bien que vous puissiez vous attendre à ce qu'une erreur "Autorisation refusée" entraîne un état de sortie de 1, vous vous trompez, comme vous le verrez dans la section suivante.

La division par zéro, cependant, vous donne un statut de sortie de 1. Vous recevez également une erreur du shell pour vous faire savoir que l'opération que vous effectuez est "inadmissible :"

$ let a=1
$ let b=0
$ let c=a/b
-bash: let: c=a/b: division by 0 (error token is "b")
$ echo $?
1

Sans erreur de shell, un état de sortie de 1 n'est pas très utile, comme vous pouvez le voir dans le premier exemple. Dans le deuxième exemple, vous savez pourquoi vous avez reçu l'erreur car Bash vous l'indique avec un message d'erreur du shell. En général, lorsque vous recevez un état de sortie de 1, recherchez les opérations non autorisées (Autorisation refusée messages) mélangés à vos réussites (par exemple répertorier tous les fichiers sous /etc , comme dans le premier exemple de cette section).

État de sortie 2

Comme indiqué ci-dessus, un avertissement du shell "Autorisation refusée" entraîne un état de sortie de 2 au lieu de 1. Pour vous le prouver, essayez de répertorier les fichiers dans /root :

$ ls /root
ls: cannot open directory '/root': Permission denied
$ echo $?
2

L'état de sortie 2 s'affiche en cas de problème d'autorisations ou d'un mot clé manquant dans une commande ou un script. Un exemple de mot clé manquant est d'oublier d'ajouter un done dans le do d'un script boucle. La meilleure méthode de débogage de script avec cet état de sortie consiste à émettre votre commande dans un shell interactif pour voir les erreurs que vous recevez. Cette méthode révèle généralement où se situe le problème.

Les problèmes de permissions sont un peu moins difficiles à déchiffrer et à déboguer que les autres types de problèmes. La seule chose que signifie "Autorisation refusée" est que votre commande ou votre script tente de violer une restriction d'autorisation.

État de sortie 126

Le statut de sortie 126 est un code d'erreur d'autorisation intéressant. Le moyen le plus simple de démontrer quand ce code apparaît est de créer un fichier de script et d'oublier de donner à ce fichier l'autorisation d'exécution. Voici le résultat :

$ ./blah.sh
-bash: ./blah.sh: Permission denied
$ echo $?
126

Ce problème d'autorisation n'est pas un problème d'accès, mais un problème de réglage, comme dans mode. Pour se débarrasser de cette erreur et recevoir un état de sortie de 0 à la place, émettez chmod +x blah.sh .

Remarque : Vous recevrez un état de sortie de 0 même si le fichier exécutable n'a pas de contenu. Comme indiqué précédemment, le "succès" est sujet à interprétation.

Je reçois un statut de sortie de 126. Ce code m'indique en fait ce qui ne va pas, contrairement aux codes plus vagues.

État de sortie 127

L'état de sortie 127 vous indique que l'une des deux choses suivantes s'est produite : soit la commande n'existe pas, soit la commande ne se trouve pas dans votre chemin ($PATH ). Ce code s'affiche également si vous essayez d'exécuter une commande qui se trouve dans votre répertoire de travail actuel. Par exemple, le script ci-dessus auquel vous avez donné l'autorisation d'exécution se trouve dans votre répertoire actuel, mais vous essayez d'exécuter le script sans spécifier où il se trouve :

$ blah.sh
-bash: blah.sh: command not found
$ echo $?
127

Si ce résultat se produit dans un script, essayez d'ajouter le chemin explicite à l'exécutable ou au script problématique. L'orthographe compte également lors de la spécification d'un exécutable ou d'un script.

[ Les lecteurs ont également apprécié : 10 commandes Linux de base que vous devez connaître. ]

État de sortie 128

L'état de sortie 128 est la réponse reçue lorsqu'un code de sortie hors plage est utilisé dans la programmation. D'après mon expérience, le statut de sortie 128 n'est pas possible à produire. J'ai essayé plusieurs actions pour un exemple, et je n'y arrive pas. Cependant, je peux produire un code adjacent à l'état de sortie 128. Si votre code de sortie dépasse 256, l'état de sortie renvoyé est votre code de sortie soustrait de 256. Ce résultat semble étrange et peut en fait créer un état de sortie incorrect. Consultez les exemples pour voir par vous-même.

En utilisant un code de sortie de 261, créez un statut de sortie de 5 :

$ bash
$ exit 261
exit
$ echo $?
5

Pour produire un état de sortie errant de 0 :

$ bash
$ exit 256
exit
$ echo $?
0

Si vous utilisez 257 comme code de sortie, votre état de sortie est 1, et ainsi de suite. Si le code de sortie est un nombre négatif, le statut de sortie résultant est ce nombre soustrait de 256. Ainsi, si votre code de sortie est 20, alors le statut de sortie est 236.

Troublant, n'est-ce pas ? La solution, pour moi, est d'éviter d'utiliser des codes de sortie réservés et hors de portée. La plage appropriée est de 0 à 255.

État de sortie 130

Si vous exécutez un programme ou un script et que vous appuyez sur Ctrl + C pour l'arrêter, votre état de sortie est 130. Cet état est facile à démontrer. Émettre ls -lR / puis appuyez immédiatement sur Ctrl-C :

$ ls -lR /
**Lots of files scrolling by**
^C
$ echo $?
130

Il n'y a pas grand chose à dire sur celui-ci. Ce n'est pas un statut de sortie très utile, mais le voici pour votre référence.

État de sortie 255

Ce statut de sortie réservé final est facile à produire mais difficile à interpréter. La documentation que j'ai trouvée indique que vous recevez l'état de sortie 255 si vous utilisez un code de sortie hors de la plage 0-255.

J'ai trouvé que ce statut peut également être produit d'autres manières. Voici un exemple :

$ ip
**Usage info for the ip command**
  
$ echo $?
255

Certaines autorités indépendantes disent que 255 est un code d'erreur d'échec général. Je ne peux ni confirmer ni infirmer cette affirmation. Je sais seulement que je peux produire l'état de sortie 255 en exécutant des commandes particulières sans options.

[ Article connexe : 10 autres commandes Linux essentielles que vous devez connaître. ]

Conclusion

Voilà :un aperçu des numéros de statut de sortie réservés, leur signification et comment les générer. Mon conseil personnel est de toujours vérifier les autorisations et les chemins pour tout ce que vous exécutez, en particulier dans un script, au lieu de vous fier aux codes d'état de sortie. Ma méthode de débogage est que lorsqu'une commande ne fonctionne pas correctement dans un script, j'exécute la commande individuellement dans un shell interactif. Cette méthode fonctionne bien mieux que d'essayer des tactiques fantaisistes avec des pauses et des sorties. J'emprunte cette voie car (la plupart du temps) mes erreurs sont liées aux autorisations. J'ai donc été formé pour commencer par là.

Amusez-vous à vérifier vos statuts, et maintenant il est temps pour moi de quitter.

[ Voulez-vous essayer Red Hat Enterprise Linux ? Télécharge le maintenant gratuitement. ]


Linux
  1. Différence entre " et " sur la ligne de commande (bash) ? ?

  2. Comment rechercher les codes de sortie pour les applications ?

  3. Passer les arguments de la ligne de commande au script Bash ?

  4. 5 Achèvement standard disponible dans la ligne de commande Linux Bash

  5. Que sont les codes de sortie Bash sous Linux

Astuces Bash pour tous les jours en ligne de commande

Comment effacer l'historique de la ligne de commande BASH sous Linux

Commande d'attente bash

Commande de sortie Bash et codes de sortie

Commande Bash printf

Comment afficher l'historique de Bash sans numéros de ligne