Comment puis-je ne canaliser que stderr en zsh?

18

En bash:

$ echo hi 2>&1 1>/dev/null | cat
$

En zsh:

$ echo hi 2>&1 1>/dev/null | cat
hi
$

Existe-t-il un moyen de ne diriger que l'erreur standard lors de la redirection de la sortie standard?

Tavian Barnes
la source

Réponses:

22

Avec zsh et avec l' mult_iosoption on (on par défaut), dans:

echo hi 2>&1 1>/dev/null | cat

Le 1> /dev/null | catest considéré comme une redirection multiple de echola sortie standard de.

La echosortie standard de So est désormais redirigée vers les deux /dev/nullet vers un canal cat(comme si vous l'utilisiez tee).

Pour annuler cette redirection multiple, vous pouvez faire:

echo hi 2>&1 >&- > /dev/null | cat

Autrement dit, fermer stdout (annulation de la tuyauterie) avant de rediriger vers /dev/null

Ou utilisez un groupe de commandes ou un sous-shell comme:

{echo hi 2>&1 1>/dev/null} | cat 
(echo hi 2>&1 1>/dev/null) | cat

De cette façon, echola sortie standard de 's n'est redirigée explicitement qu'une seule fois (la redirection de canal est appliquée au groupe / sous-shell et héritée par echo).

Ou vous pouvez désactiver multioscomplètement:

(setopt nomultios; echo hi 2>&1 > /dev/null | cat)

Alternativement, vous pouvez utiliser la substitution de processus au lieu d'un canal:

echo hi 2> >(cat) > /dev/null

Sachez toutefois que lorsque le contrôle des travaux est désactivé (comme dans les scripts), le catprocessus s'exécute de manière asynchrone (comme s'il était démarré avec &).

Stéphane Chazelas
la source
3
Merci! Une autre façon de le contourner est (echo hi 2>&1 1>/dev/null) | cat.
Tavian Barnes
1
@TavianBarnes, bon point, merci. Je l'ai ajouté à la réponse pour être complet. Il fonctionne également avec un groupe de commandement ( {echo...}|cat)
Stéphane Chazelas