Quand utiliser la redirection vers stderr dans les scripts shell

15

Je sais que des utilitaires bien comportés comme grep envoient des messages "normaux" à stdout et des messages d'erreur à stderr.

$ grep '^foo' file1 file2
file1:foo
grep: file2: No such file or directory

Lorsque j'écris moi-même des scripts shell, j'ai souvent du mal à décider quelle sortie et quels messages je dois présenter sur stderr, ou si je devrais m'embêter du tout.

J'aimerais connaître les bonnes pratiques: quand rediriger un message vers stderr est-il nécessaire et raisonnable, et quand non?

"Cela dépend", bien sûr, mais avez-vous des idées qui pourraient m'aider à prendre ces décisions?

Afin d'adapter cette question subjective au format, je voudrais encourager des réponses qui répondent au "pourquoi", et qui sont éclairées par l'expérience et si possible appuyées par des faits.

glts
la source
@rush l'explique parfaitement. J'imprime généralement des rapports de progression sur stderr pour les longs scripts.
terdon

Réponses:

12

Lorsque j'écris moi-même des scripts shell, j'ai souvent du mal à décider quelle sortie et quels messages je dois présenter sur stderr, ou si je devrais m'embêter du tout.

Le silence est d'or. Rien de sortie si tout va bien.

J'aimerais connaître les bonnes pratiques: quand rediriger un message vers stderr est-il nécessaire et raisonnable, et quand non?

La façon la plus simple de séparer stderr de stdout: imaginez simplement que toutes les sorties de vos scripts seront redirigées vers une autre commande via pipe. Dans ce cas, vous devez conserver toutes les notifications dans stderr, car de telles informations inattendues dans stdout peuvent interrompre la séquence de canaux.

Parfois aussi dans des tuyaux comme celui-ci:

command1 | while read line ; do command2 ; done | command3

vous devez transmettre quelque chose command2à la sortie des utilisateurs. Le moyen le plus simple sans fichiers temporaires est stderr.

se ruer
la source
Merci pour l'idée "imaginez une pipe". Parfois, j'ai déployé des scripts qui ne font que "notifier" ( echocertaines variables, montrer ce qui a été fait, montrer la progression). J'hésite à tout mettre sur stderr car ces messages de journalisation sont tous les scripts qui sortiront jamais. Je ne sais pas comment appliquer l'idée de tuyau dans ces situations.
glts
1
Les programmes @glts sont toujours modifiés et améliorés. Bien que les scripts que vous mentionnez ne produisent pas de données maintenant, ils peuvent plus tard ou vous pouvez les utiliser comme points de départ pour d'autres scripts qui le font. Si vous suivez la convention pour commencer, vous aurez beaucoup moins de surprises plus tard. OTOH, si vous voulez simplement enregistrer la sortie dans un fichier, vous devez rediriger stderr, c'est donc un compromis comme tout le reste.
Joe
+1 Une autre paraphrase: assurez-vous que stdout est toujours lisible par machine ou contient au moins des données textuelles utiles dans un format cohérent.
tripleee
2

J'écris généralement tout ce qui concerne le fonctionnement de l'application stderr, stdoutest réservé aux données.

Imaginez une application comme cat. Lorsque vous l'utilisez pour lire l'entrée et la transmettre à une autre application (via un canal), vous ne voulez pas que la sortie soit jonchée de messages d'état.

Tout ce qui pourrait être intéressant pour une autre application ou un post-processeur pour mon application va stdout, tout ce qui ne concerne que l'interne de mon application va l'être stderr.

Der Hochstapler
la source
0

Ma préférence personnelle est d'envoyer des messages d'erreur et des exceptions à stderret des messages d'information à stdout. OMI, stderrest pour toutes les exceptions et donc, ma convention.

unnut
la source