web-dev-qa-db-fra.com

Shell: redirige stdout vers / dev / null et stderr vers stdout

J'ai vu cette question intéressante lors d'un commentaire sur cyberciti.biz .

Que j'ai trouvé que je ne peux même pas trouver un moyen flexible de le faire dans une commande en ligne avec sh.

Dans la mesure où ma pensée pour la solution est:

tmp_file=`mktemp`
(./script 2>$tmp_file >/dev/null; cat $tmp_file) | ./other-script
rm tmp_file

Mais vous voyez, ce n'est pas synchrone, et fatalement, c'est si moche.

Bienvenue à partager votre esprit à ce sujet. :)

46
Shou Ya

Tu veux

./script 2>&1 1>/dev/null | ./other-script

L'ordre ici est important. Supposons que stdin (fd 0), stdout (fd 1) et stderr (fd 2) sont tous initialement connectés à un tty, donc

0: /dev/tty, 1: /dev/tty, 2: /dev/tty

La première chose qui se met en place est le tuyau. Le stdin d'un autre script est connecté au tuyau, et la sortie standard du script est connectée au tuyau, donc les descripteurs de fichier du script ressemblent jusqu'à présent à:

0: /dev/tty, 1: pipe, 2: /dev/tty

Ensuite, les redirections se produisent, de gauche à droite. 2>&1 fait fd 2 aller partout où fd 1 va actuellement, qui est le tube.

0: /dev/tty, 1: pipe, 2: pipe

Enfin, 1>/dev/null redirige fd1 vers /dev/null

0: /dev/tty, 1: /dev/null, 2: pipe

Résultat final, la sortie standard du script est réduite au silence et son stderr est envoyé par le canal, qui se retrouve dans le stdin d'un autre script.

Voir aussi http://bash-hackers.org/wiki/doku.php/howto/redirection_tutorial

Notez également que 1>/dev/null est synonyme de, mais plus explicite que >/dev/null

99
geirha

Que dis-tu de ça:

./script 3>&1 1>/dev/null 2>&3 | ./other-script

L'idée est de "sauvegarder" le descripteur stdout, de fermer la stdout d'origine, puis de rediriger strerr vers la stdout enregistrée.

Son beaucoup semblable à la solution fournie par geirha, mais son plus explicite (le codage bash peut facilement devenir très obscurci).

5
Zaar Hai