État de sortie non nul pour une sortie propre

15

Est-il acceptable de renvoyer un code de sortie différent de zéro si le programme en question s'est correctement exécuté? Par exemple, disons que j'ai un programme simple qui (uniquement) fait ce qui suit:

Le programme prend N arguments. Il renvoie un code de sortie de min (N, 255). Notez que tout N est valide pour le programme.

Un programme plus réaliste pourrait renvoyer différents codes pour des programmes exécutés avec succès qui signifient différentes choses. Ces programmes devraient-ils plutôt écrire ces informations dans un flux, comme stdout?

Thomas Eding
la source

Réponses:

24

Cela dépend de l'environnement, mais je dirais que c'est un style médiocre.

Les systèmes de type Unix ont une convention forte selon laquelle un état de sortie de 0 indique la réussite et tout état de sortie non nul indique l'échec. Certains programmes, mais pas tous, distinguent différents types de défaillances avec différents codes de sortie différents de zéro; par exemple, grepretourne généralement 0 si le modèle a été trouvé, 1 s'il ne l'était pas et 2 (ou plus) s'il y avait une erreur telle qu'un fichier manquant.

Cette convention est à peu près câblée dans les shells Unix. Par exemple, dans sh, bashet d'autres shells de type Bourne, l' ifinstruction traite un état de sortie 0 comme succès / vrai et un état de sortie non nul comme échec / faux:

if your-command
then
    echo ok
else
    echo FAILURE
fi

Je pense que les conventions sous MS Windows sont similaires.

Maintenant, rien ne vous empêche d'écrire votre propre programme qui utilise des codes de sortie non conventionnels, surtout si rien d'autre ne va interagir avec lui, mais sachez que vous violez une convention bien établie, et il pourrait revenir et vous mordre plus tard .

La manière habituelle pour un programme de renvoyer ce type d'informations est de l'imprimer à stdout:

status = $(your-command)
echo Result is $status
Keith Thompson
la source
7
+1 pour expliquer la convention, cette approche briserait la plupart de mes scripts shell si je mettais un set -equelque part.
Benjamin Bannier
De même que grep, diffrenvoie 1 lorsque des différences sont trouvées; et> 1 en cas d'erreur.
7heo.tk
6

Dépend de ce que votre environnement attend.

Mon préféré pour la bizarrerie, de Wikipedia :

Dans OpenVMS, le succès est indiqué par des valeurs impaires et l'échec par des valeurs paires. La valeur est un entier de 32 bits avec des sous-champs: bits de contrôle, numéro d'installation, numéro de message et gravité. Les valeurs de gravité sont divisées entre succès (succès, information) et échec (avertissement, erreur, fatal).

Facture
la source
4

Je pense qu'il y a un précédent si le code de sortie renvoie des informations significatives et pertinentes à l'appelant et que la définition du succès n'est pas vraiment binaire. Le précédent auquel je pense est la robocopie qui renvoie une multitude de choses différentes selon ce qui s'est passé .

J'ajouterai que nous finissons toujours par avoir un débogage à cause de cela - la plupart des utilitaires supposent que le code de sortie 0 == succès, alors paniquez lorsque robocopy renvoie 1 parce qu'il a copié des trucs non nuls parce qu'il n'a pas copié des trucs mais n'a pas '' t obtenir une erreur non plus.

Wyatt Barnett
la source
2

ne pas retourner 0 pour une exécution réussie est une mauvaise idée, car cela peut créer de la confusion pour ceux qui exécutent votre programme. Que se passe-t-il si certains exécutent votre programme plus de 100 fois avec des entrées différentes et souhaitent savoir combien ont échoué ou se sont déroulés avec succès?

Si vous avez un programme qui a plusieurs chemins de retour réussis qui peuvent tous signifier des choses différentes, je dirais que c'est un signe que votre programme est mal conçu.

Ryathal
la source
2

Je connais un cas qui me semble acceptable. Je connais un cadre de test qui se termine avec le nombre total d'échecs de test. Ainsi, par exemple, si le lanceur de test se termine sans échec, il se termine avec zéro. Si un test a échoué, même si le testeur lui-même s'est correctement exécuté, il se termine avec un 1. Si deux échouent, il renvoie 2, etc. Cela va jusqu'à 250, ce qui signifie "250 échecs de test ou plus".

Il utilise des codes de sortie> 250 pour signifier des sorties anormales.

Bien que cela viole la convention, cela fonctionne bien dans la pratique.

Bryan Oakley
la source
3
Je ne pense pas que cela ne violer la convention - le test est réussi s'il n'y a pas d' erreurs; tout code de résultat différent de zéro indique l'échec des tests.
Bevan
1
C'est "quitter avec un statut d'erreur pour indiquer plus de 0 erreurs" et bien qu'il puisse violer la sémantique commune exacte du statut de sortie, il ne viole certainement pas la plus grande convention "0 est OK, tout ce qui est supérieur à 0 est une erreur" .
Vatine
2

Cela dépend vraiment de ce que vous essayez de transmettre avec le code. DB2, par exemple, renvoie 100 si aucune donnée n'est trouvée, diverses autres valeurs positives pour les avertissements et des valeurs négatives pour les erreurs. Oracle fait quelque chose de similaire.

Ainsi, s'il existe différents états de réussite, il peut être utile d'utiliser différentes valeurs de retour.

Matthew Flynn
la source
2

Un bon exemple: man sa-update (spamassassin)

CODES DE SORTIE

  • Un code de sortie de 0 signifie qu'une mise à jour était disponible et qu'elle a été téléchargée et installée avec succès si --checkonly n'était pas spécifié.
  • Un code de sortie de 1 signifie qu'aucune nouvelle mise à jour n'était disponible.
  • Un code de sortie de 2 signifie ...

Dans ce cas, la sortie 1 est simplement un code informatif. Cependant, si j'avais écrit le code, je n'aurais pas choisi 1 car il s'agit généralement d'une panne de secteur.

Evert
la source