Wie kann ich nur stderr in zsh leiten?

18

In der Bash:

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

Während in zsh:

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

Gibt es eine Möglichkeit, nur Standardfehler umzuleiten, während Standard heraus umgeleitet wird?

Tavian Barnes
quelle

Antworten:

22

Mit zsh und mit der mult_iosOption on (standardmäßig on) in:

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

Das 1> /dev/null | catwird als mehrfache Umleitung von echo's stdout angesehen.

Also wird echostdout jetzt zu beiden umgeleitet /dev/nullund eine Pipe zu cat(als ob benutzt tee).

Um diese Mehrfachumleitung abzubrechen, haben Sie folgende Möglichkeiten:

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

Das heißt, Sie schließen stdout (brechen die Rohrleitung ab), bevor Sie zu umleiten /dev/null

Oder verwenden Sie eine Befehlsgruppe oder Subshell wie:

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

Auf diese Weise wird echodie stdout nur einmal explizit umgeleitet (die Pipe-Umleitung wird auf die Gruppe / Subshell angewendet und von übernommen echo).

Oder Sie können multiosinsgesamt deaktivieren :

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

Alternativ können Sie die Prozessersetzung anstelle einer Pipe verwenden:

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

Beachten Sie jedoch, dass bei deaktivierter Jobsteuerung (wie in Skripten) der catProzess asynchron ausgeführt wird (als würde er mit gestartet &).

Stéphane Chazelas
quelle
3
Vielen Dank! Ein anderer Weg, um es zu umgehen, ist (echo hi 2>&1 1>/dev/null) | cat.
Tavian Barnes
1
@TavianBarnes, guter Punkt, danke. Ich habe es der Vollständigkeit halber zur Antwort hinzugefügt. Es funktioniert auch mit einer Befehlsgruppe ( {echo...}|cat)
Stéphane Chazelas