Ce qui ne fonctionne pas :
La raison de la dernière commande que vous avez citée :
cmd 1>/dev/null 2>&1 | grep pattern
ne fonctionne pas, provient d'une confusion sur l'ordre dans lequel la redirection fonctionne. Vous vous attendiez à ce que la dernière redirection citée soit appliquée à celles qui la précèdent sur chaque sortie, de sorte que la sortie du descripteur de fichier de sortie standard original (1) aille vers /dev/null, et que la sortie vers le descripteur de fichier d'erreur standard (2) aille vers la sortie standard originale.
Toutefois, ce n'est pas ainsi que fonctionne la redirection de l'interpréteur de commandes. Chaque redirection entraîne le "remappage" des descripteurs de fichiers en fermant la "source" et en dupliquant la "destination" dans celle-ci (voir l'instruction man
pages de dup(2)
et close(2)
), dans l'ordre. Cela signifie que dans votre commande la sortie standard est d'abord remplacée par /dev/null
et l'erreur standard est remplacée par la sortie standard, soit /dev/null
déjà.
Ce qui marche :
Par conséquent, pour obtenir l'effet désiré, il suffit d'inverser les redirections. Ainsi, l'erreur standard sera redirigée vers la sortie standard, et la sortie standard originale sera redirigée vers /dev/null
:
cmd 2>&1 >/dev/null | grep pattern
(notez que le 1
avant >
n'est pas nécessaire - pour la redirection de la sortie, la sortie standard est la valeur par défaut)
Addendum : Charlie a mentionné la redirection vers &-
pour fermer un descripteur de fichier. Si vous utilisez un shell interactif qui supporte cette extension ( bash
et certaines autres implémentations le font mais pas toutes et c'est non standard ), vous pouvez également procéder de la manière suivante :
cmd 2>&1 >&- | grep pattern
C'est peut-être mieux - cela peut faire gagner du temps, car lorsque la commande essaie d'écrire sur la sortie standard, l'appel à write
peut échouer immédiatement sans attendre un changement de contexte dans le noyau et la gestion du pilote. /dev/null
(en fonction de l'implémentation de l'appel système - certains peuvent l'attraper dans l'appel système de l'utilisateur). libc
et certains peuvent également avoir un traitement spécial pour les fonctions /dev/null
). S'il y a beaucoup de sorties, cela peut être intéressant, et c'est plus rapide à taper.
Cela fonctionnera surtout parce que la plupart des programmes ne se soucient pas de ne pas écrire sur la sortie standard (qui vérifie vraiment la valeur de retour de la commande printf
?) et ne se souciera pas que la sortie standard soit fermée. Mais certains programmes peuvent se sauver avec un code d'échec si write
échoue - généralement les processeurs de blocs, les programmes utilisant une bibliothèque prudente pour les E/S ou la journalisation vers la sortie standard. Donc si cela ne fonctionne pas, rappelez-vous que c'est une cause probable et essayez de /dev/null
.