Rediriger stdout seul, comme lors d'un pipe stdin
Résolu
Bonjour,
Voici mon problème :
j'ai une commande au milieu de multiples pipe dont je voudrais traiter la sortie STDERR différemment. Je m'explique:
..... commande1 | commande2 .....
STDOUT de "commande1" va donc vers "commande2"
et STDERR de "commande1" va s'afficher sur mon terminal local
Ce que je voudrais faire, c'est rediriger ce STDERR vers un programme qui va le modifier, puis renvoyer cette modification pour qu'elle s'affiche sur mon terminal
Exemple:
cmd1 2> >(grep txt) | cmd2
Sauf que dans cet exemple, la sortie du "grep txt" n'est plus redirigée vers mon terminal. Je n'arrive pas à trouver de solution.
Sauriez-vous m'aider?
Merci:)
Voici mon problème :
j'ai une commande au milieu de multiples pipe dont je voudrais traiter la sortie STDERR différemment. Je m'explique:
..... commande1 | commande2 .....
STDOUT de "commande1" va donc vers "commande2"
et STDERR de "commande1" va s'afficher sur mon terminal local
Ce que je voudrais faire, c'est rediriger ce STDERR vers un programme qui va le modifier, puis renvoyer cette modification pour qu'elle s'affiche sur mon terminal
Exemple:
cmd1 2> >(grep txt) | cmd2
Sauf que dans cet exemple, la sortie du "grep txt" n'est plus redirigée vers mon terminal. Je n'arrive pas à trouver de solution.
Sauriez-vous m'aider?
Merci:)
A voir également:
- Rediriger stdout seul, comme lors d'un pipe stdin
- Comment rediriger une adresse mail - Guide
- Comment imprimer un tableau excel sur une seule page - Guide
- Assistant google se lance tout seul avec écouteurs - Forum Accessoires & objets connectés
- Comment regrouper plusieurs pdf en un seul - Guide
- Son dans un seul écouteur avec fil - Forum Audio
3 réponses
hello
$ (echo aaa ; echo bbb>&2 ; echo ccc) 2> >(sed 's/^/stderr: /' >&2) | sed 's/^/stdout: /' stdout: aaa stdout: ccc stderr: bbb $
En fait tu peux rediriger le flux stderr sur le flux stdout et ainsi le récupérer dans ton pipe (2>&1).
Tu peux rediriger le flux qui était envoyé initialement dans stdout vers /dev/null (1>/dev/null) pour qu'il ne perturbe pas le flux d'erreur. Attention à l'ordre dans lequel tu passes les redirections car dans le mauvais ordre, tu vas rediriger les deux flux vers /dev/null. La syntaxe correcte est indiquée ci-dessous :
Comme tu le vois ici, le flux d'erreur traverse bien le pipe puisque grep rattrape bien uniquement la ligne contenant vpnc dans cet exemple.
Bonne chance
Tu peux rediriger le flux qui était envoyé initialement dans stdout vers /dev/null (1>/dev/null) pour qu'il ne perturbe pas le flux d'erreur. Attention à l'ordre dans lequel tu passes les redirections car dans le mauvais ordre, tu vas rediriger les deux flux vers /dev/null. La syntaxe correcte est indiquée ci-dessous :
(mando@silk) (/etc) $ find . find: . ./shadow- ./kernel-img.conf ./esound ./esound/esd.conf ./.pwd.lock ./acpi ./acpi/events ./acpi/events/RadioPowerTest ./udev "./lvm/cache": Permission non accordée ... (mando@silk) (/etc) $ find . 2>&1 1>/dev/null find: "./lvm/cache": Permission non accordée find: "./vpnc": Permission non accordée find: "./ppp/peers": Permission non accordée find: "./ssl/private": Permission non accordée find: "./chatscripts": Permission non accordée (mando@silk) (/etc) $ find . 2>&1 1>/dev/null | grep vpnc find: "./vpnc": Permission non accordée
Comme tu le vois ici, le flux d'erreur traverse bien le pipe puisque grep rattrape bien uniquement la ligne contenant vpnc dans cet exemple.
Bonne chance
Salut,
Merci, mais le problème c'est que dans cet exemple le flux 1 original (STDOUT) est perdu.
Or il est très important et doit être transmis à "cmd2"
cmd1 2> >(grep txt) | cmd2
->Le STDOUT est transmis à cmd2 par le pipe
->Le STDERR, pour cmd1 doit être traité à part, comme si on l'envoyait dans un 2ème pipe
Merci, mais le problème c'est que dans cet exemple le flux 1 original (STDOUT) est perdu.
Or il est très important et doit être transmis à "cmd2"
cmd1 2> >(grep txt) | cmd2
->Le STDOUT est transmis à cmd2 par le pipe
->Le STDERR, pour cmd1 doit être traité à part, comme si on l'envoyait dans un 2ème pipe
Autre solution tu rediriges le flux de stderr dans un fichier temporaire et ensuite tu cat + pipe ce fichier pour commande 2.
Bonne chance
commande 2>/tmp/toto | commande_stdout && cat /tmp/toto | commande_stderr
Bonne chance
Merci également,
La solution de dubdek correspond mieux à mon problème.
Car en passant par un fichier temporaire comme tu le suggères, la totalité du flux STDERR serait d'abord enregistrée sur le disque avant d'être traitée. Or je cherchais à traiter ce flux au fur et à mesure, comme lors d'un pipe, et ne pas le conserver sur disque.
Et en cas de traitement concurrent, si le même fichier temporaire est utilisé, cela posera de gros soucis
La solution de dubdek correspond mieux à mon problème.
Car en passant par un fichier temporaire comme tu le suggères, la totalité du flux STDERR serait d'abord enregistrée sur le disque avant d'être traitée. Or je cherchais à traiter ce flux au fur et à mesure, comme lors d'un pipe, et ne pas le conserver sur disque.
Et en cas de traitement concurrent, si le même fichier temporaire est utilisé, cela posera de gros soucis
Au moment ou tu cat /tmp/toto, rien n'empêcherait de mettre un grep pour ne conserver que les lignes qui t'intéresse.
Mais la solution de dubcek est effectivement meilleure, car elle évite de passer par un fichier temporaire (ce qui évite pas mal de soucis, comme vérifier que le fichier temporaire n'existe pas déjà , le supprimer à la fin etc.). J'avoue que je ne pensais pas qu'on pouvait rediriger un flux avec > dans une commande, pour moi c'était forcément dans un fichier... donc j'ai appris quelque chose.
Mais la solution de dubcek est effectivement meilleure, car elle évite de passer par un fichier temporaire (ce qui évite pas mal de soucis, comme vérifier que le fichier temporaire n'existe pas déjà , le supprimer à la fin etc.). J'avoue que je ne pensais pas qu'on pouvait rediriger un flux avec > dans une commande, pour moi c'était forcément dans un fichier... donc j'ai appris quelque chose.
cmd1 2> >(grep txt)>&2 | cmd2
En le mettant dedans ça marche mieux effectivement !
Merci! :-)