Tuyauterie à la fois stdout et stderr dans bash?

156

Il semble que les nouvelles versions de bash ont l' &>opérateur, qui (si je comprends bien), redirige à la fois stdout et stderr vers un fichier ( &>>ajoute plutôt au fichier, comme Adrian l'a clarifié).

Quel est le moyen le plus simple de réaliser la même chose, mais à la place de passer à une autre commande?

Par exemple, dans cette ligne:

cmd-doesnt-respect-difference-between-stdout-and-stderr | grep -i SomeError

Je voudrais que le grep corresponde au contenu à la fois dans stdout et stderr (effectivement, les combiner en un seul flux).

Remarque : cette question concerne la tuyauterie, pas la redirection - il ne s'agit donc pas d'un double de la question dont elle est actuellement marquée comme duplicata.

Andrew Ferrier
la source
Voir la deuxième réponse ( stackoverflow.com/a/637834/1129642 ) sur la question liée pour savoir comment diriger à la fois stdout et stderr. Pas besoin d'une autre question.
Marki555
4
@triplee Pas une copie exacte, n'est-ce pas? Pipe vs redirection vers un fichier?
Benjamin W.
@BenjaminW Il y a au moins une réponse qui résout les deux scénarios, bien que ce ne soit pas la réponse acceptée. C'est une question assez courante, donc nous pourrions probablement trouver un meilleur doublon, ou demander à un modérateur de les fusionner - ou même, dans le pire des cas, créer un tout nouveau canonique pour ce sujet. Si vous trouvez une meilleure dupe, proposez-la par tous les moyens. Merci d'avance.
tripleee du
12
@tripleee Résout, oui, mais aucune des réponses n'utilise le |&raccourci, qui je pense est de loin la solution la plus pratique pour "rediriger à la fois stdout et stderr vers un tube".
Benjamin W.
3
Ce n'est pas un double de la question liée, et il n'était pas clair que la réponse de Marko faisait ce que je voulais. De plus, il ne mentionne pas | &. Voter pour rouvrir.
Martin Bonner soutient Monica

Réponses:

163

(Notez que les &>>file ajouts à un fichier tandis &>que redirigeraient et écraseraient un fichier existant précédemment.)

Pour combiner stdoutet stderrvous redirigeriez ce dernier vers le premier en utilisant 2>&1. Cela redirige stderr (descripteur de fichier 2) vers stdout (descripteur de fichier 1), par exemple:

$ { echo "stdout"; echo "stderr" 1>&2; } | grep -v std
stderr
$

stdoutva à stdout, stderrva à stderr. grepvoit seulement stdout, donc stderrimprime sur le terminal.

D'autre part:

$ { echo "stdout"; echo "stderr" 1>&2; } 2>&1 | grep -v std
$

Après avoir écrit à la fois dans stdout et stderr, 2>&1redirige stderr vers stdout et grepvoit les deux chaînes sur stdin, filtrant ainsi les deux.

Vous pouvez en savoir plus sur la redirection ici .

Concernant votre exemple (POSIX):

cmd-doesnt-respect-difference-between-stdout-and-stderr 2>&1 | grep -i SomeError

ou, en utilisant >=bash-4:

cmd-doesnt-respect-difference-between-stdout-and-stderr |& grep -i SomeError
Adrian Frühwirth
la source
Merci pour la clarification &>>. J'ai corrigé ma question.
Andrew Ferrier
18
J'ai ajouté votre exemple à ma réponse, juste au cas où il ne serait pas évident sur la base de mes exemples donnés. En remarque, vous pouvez également utiliser le spécifique bash |&au lieu de 2>&1 |.
Adrian Frühwirth
13
Note d' |&accompagnement sur le raccourci proposé par @ AdrianFrühwirth pour les futurs lecteurs: cette fonctionnalité n'est prise en charge qu'avec la bashversion 4+. Si vous utilisez 3 ou moins, vous devez vous en tenir à 2>&1 |.
tomocafe
3
La redirection Bash est très bien expliquée ici . @ AdrianFrühwirth a fait du bon travail, le lien collé va encore plus loin. Parfois, je souhaite que la documentation officielle de Bash soit aussi bonne.
David Andreoletti
112

Bash a un raccourci pour 2>&1 |, à savoir |&, quels tuyaux à la fois stdout et stderr (voir le manuel ):

cmd-doesnt-respect-difference-between-stdout-and-stderr |& grep -i SomeError

Cela a été introduit dans Bash 4.0, voir les notes de publication .

Benjamin W.
la source
Merci d'avoir ajouté ceci pour l'exhaustivité. Je vais garder l'autre réponse correcte car de nombreuses personnes utilisent encore bash pré-4.0. Mais c'est utile.
Andrew Ferrier
9
Plus particulièrement peut-être, le Bash fourni sur macOS est trop ancien pour le supporter.
Flimm
@Flimm mais le zsh n'est pas
Trenton
1
Puisque ksh utilise | & pour coproc, cela semble être un mauvais choix pour un raccourci inutile. Je déteste voir des lignes avec une pile de dups et de redirections autant que le prochain, mais il y a quelque chose à dire pour être explicite ... et je m'excuse que ce commentaire n'ajoute pas grand-chose. Je voulais juste exprimer le dégoût pour la sténographie sans voter contre une réponse réellement utile, car c'est bien que les gens voient cela. Je ne savais pas cela, alors merci de m'en avoir informé.
Paul Hodges
@PaulHodges Je conviens qu'il n'est pas portable - j'aime surtout l'utiliser pour des sessions interactives Bash pour éviter de trop taper.
Benjamin W.