Existe-t-il une directive officielle POSIX, GNU ou autre indiquant l'endroit où les rapports d'avancement et les informations de journalisation (des choses telles que "Doing foo; foo done") doivent être imprimés? Personnellement, j'ai tendance à les écrire sur stderr pour pouvoir rediriger stdout et obtenir uniquement la sortie réelle du programme. On m'a récemment dit que ce n'était pas une bonne pratique puisque les rapports d'avancement ne sont pas réellement des erreurs et que seuls les messages d'erreur doivent être imprimés sur stderr.
Les deux positions ont du sens, et vous pouvez bien sûr choisir l’une ou l’autre en fonction des détails de ce que vous faites, mais je voudrais savoir s’il existe une norme communément acceptée à cet égard. Je n'ai pas pu trouver de règles spécifiques dans POSIX, dans les normes de codage GNU, ni dans aucune autre liste de bonnes pratiques largement acceptée.
Nous avons quelques questions similaires, mais elles ne traitent pas de cette question précise:
Quand utiliser la redirection vers stderr dans les scripts de shell : La réponse acceptée suggère ce que j'ai tendance à faire: conservez la sortie finale du programme sur stdout et sur toute autre chose pour stderr. Cependant, ceci est simplement présenté comme une opinion d'utilisateur, bien que soutenue par des arguments.
Le message d'utilisation doit-il aller à stderr ou stdout? : Ceci est spécifique aux messages d’aide mais cite la norme de codage GNU. C'est le genre de chose que je recherche, mais pas uniquement pour aider les messages.
Alors, y a-t-il des règles officielles sur l'endroit où les rapports d'avancement et autres messages informatifs (qui ne font pas partie du résultat réel du programme) doivent être imprimés?
stdout
avec les résultats est un moyen sûr de rendre les résultats inutiles. Si vous avez besoin de transférer les résultats vers un autre programme, celui-ci devra séparer les résultats des filateurs. De plus, si vous redirigez la sortie vers un fichier, vous ne pourrez pas voir les fileurs. A MON HUMBLE AVIS.stdout
c’est en fait un moyen sûr et correct de relayer les filateurs et d’autres messages informatifs, mais comme le disent de nombreux programmeurs, «le silence est d’or. Ne rien produire si tout va bien. donc en fait, stderr est toujours utilisé pour faire en raison de la définition vague et StdOut aussi peut briser le tube sequence.for guide officielstderr
pour signaler les messages d'erreur, sauf lorsqu'un--verbose
indicateur est utilisé, auquel cas les rapports d'avancement sont également inclus.Réponses:
Posix définit les flux standards ainsi :
La bibliothèque GNU C décrit les flux standard de la même manière:
Ainsi, les définitions standard donnent peu d'indications sur l'utilisation des flux au-delà des «sorties conventionnelles / normales» et «sorties diagnostiques / d'erreurs». En pratique, il est courant de rediriger l'un ou l'autre de ces flux vers des fichiers et des pipelines, où les indicateurs de progression poseront problème. . Certains systèmes surveillent même les
stderr
résultats et le considèrent comme un signe de problèmes. Les informations de progression purement auxiliaires sont donc problématiques sur l'un ou l'autre flux.Au lieu d'envoyer des indicateurs de progression de manière inconditionnelle à l'un ou l' autre des flux standard, il est important de reconnaître que le résultat des progrès n'est approprié que pour les flux interactifs . Dans cet esprit, je vous recommande d'écrire les compteurs de progression uniquement après avoir vérifié si le flux est interactif (par exemple, avec
isatty()
) ou s'il est explicitement activé par une option de ligne de commande. Cela est particulièrement important pour les compteurs de progression qui s'appuient sur le comportement de mise à jour du terminal, comme les barres%-complètes.Pour certains messages de progression très simples («Démarrage de X» ... «Terminé avec X»), il est plus raisonnable d'inclure la sortie même pour les flux non interactifs. Dans ce cas, réfléchissez à la manière dont les utilisateurs pourraient interagir avec les flux, tels que la recherche avec
grep
ou la pagination avecless
ou la surveillance avectail -f
. S'il est logique de voir les messages de progrès dans ces contextes, ils seront beaucoup plus faciles à consommerstdout
.la source
N% done
choses commedoing foo
et àfoo done
. Ces derniers doivent toujours être conservés car ils sont utilisés pour le débogage lorsqu'ils sont redirigés vers un fichier. Donc, votre suggestion de vérifier si le flux est interactif ne s'applique pas (bien que généralement une très bonne idée).curl
etyum
. Dans ce cas, je pense savoir si et comment l'utilisateur voudrait interagir avec la sortie viagrep
ouless
ou des outils similaires.POSIX définit l'erreur standard comme
Cela ne limite pas son utilisation aux seuls messages d'erreur. Je considérerais les informations de progression comme une sortie de diagnostic, ce qui en fait une erreur standard.
la source
stdout
est mis en ligne par défaut, alors qu'ilstderr
est sans tampon , il enstderr
va de même pour l'écriture de texte progressif / barres / filateurs ne contenant pas de nouvelle ligne. (Si vous écrivez un tel texte,stdout
vous devez encombrer vos appels de sortie de progression avecstdout.flush()
pour le rendre visible).stdout
, vous devez vider même si votre texte ne contient une nouvelle ligne si vous voulez que vos rapports d'étape pour montrer réellement implémentés en temps réel redirigé.Posix est un peu plus concret sur « des informations de diagnostic » dans Shell et utilitaires , 1.4: Utilitaire Description Par défaut (Souligné par ):
IANASL, mais j’interprète cela comme signifiant que stderr n’aura de sortie que si l’utilitaire renvoie un code de sortie d’erreur. Etant donné que cela ne devrait pas être le cours normal des événements pour une exécution réussie, aucune information de progression ne doit être imprimée par un utilitaire POSIX sauf en cas d'erreur (sauf indication contraire, bien sûr, etc.).
la source
En vertu du principe d'exclusion, il ne peut aller que jusqu'à stderr. Oui, je sais que vous avez demandé une spécification officielle, que je ne peux pas vous présenter au-delà du lien vers la spécification POSIX, donnée par Stephen Kitt, qui stipule que stderr est utilisé à des fins de diagnostic.
Le point le plus important est que stdin et stdout ont une fonction qui interdit l'impression de rapports de progression sur stdout - ils forment bien sûr la séquence de canaux qui, dans les commandes de shell Unix, n'est pas qu'un simple effet secondaire, mais constitue le cœur même de la puissante approche de pipeline. .
Alors. Rien sauf la vraie "charge utile" de votre programme n'appartient à stdout. Si votre programme n'a pas de sortie, rien ne devrait aller à stdout. Cela laisse stderr pour tout le reste , y compris les rapports d'avancement.
Certes, cela laisse un trou - il serait probablement bien d’avoir un "stdfluff" ou quelque chose du genre qui n’a pour but ni la sortie ni les erreurs, mais les rapports de progression, le débogage, etc. En fait, rien ne vous empêche de le faire, c’est-à-dire que vous pouvez imprimer votre progression dans le descripteur de fichier 3. Exemple:
Cela ne produit aucune sortie. (*)
Ceci est imprimé sur fd-3, qui est redirigé sur stdout.
(*) Le premier exemple ne produit aucune sortie mais reste un peu tiré par les cheveux; les
open
échoue et$!
contiendraitno such file or directory
; Prenez ceci comme exemple, il ne faut bien sûr pas en faire un usage sérieux. Dans un programme réel, si vous souhaitez emprunter cette voie, vous pouvez vérifier si vous pouvez l'/dev/fd/3
utiliser ou non, et prendre cela comme un indice permettant d'activer ou non vos rapports d'avancement. vous devriez le faire assez tôt pour ne pas vous tromper deopen
fichiers personnels et autres ...la source
fd-3
? La troisième disquette?Le message d'utilisation doit aller à stdout si l'utilisateur l'a invoqué avec
--help
et à stderr s'il s'est trompé. L'imprimer sur stderr inconditionnellement est odieux, car cela rend plus difficile sa visualisation avec un pager / grep / etc.Aussi, puis-je suggérer une troisième voie: ouvrir / dev / tty pour les rapports d’avancement / tourneurs / etc.
la source
--help
ni de messages d'aide. Veuillez relire la question, s'il vous plaît.