Jak mogę przesyłać tylko stderr w Zsh?

18

W bash:

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

Podczas pobytu w Zsh:

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

Czy można przekierować tylko standardowy błąd podczas przekierowywania standardowego?

Tavian Barnes
źródło

Odpowiedzi:

22

Z zsh i mult_ioswłączoną opcją (domyślnie włączone) w:

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

Jest 1> /dev/null | catto postrzegane jako wielokrotne przekierowanie standardowego echowyjścia.

Tak echojest standardowe wyjście jest teraz skierowane do obu /dev/nulli potok cat(tak jak przy użyciu tee).

Aby anulować wielokrotne przekierowanie, możesz:

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

Oznacza to, że zamknięcie stdout (anulowanie orurowania) przed przekierowaniem do /dev/null

Lub użyj grupy poleceń lub podpowłoki, takich jak:

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

W ten sposób standardowe echowyjście jest przekierowywane tylko raz (przekierowanie potoku jest stosowane do grupy / podpowłoki i dziedziczone przez echo).

Lub możesz multioscałkowicie wyłączyć :

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

Alternatywnie możesz użyć podstawienia procesu zamiast potoku:

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

Należy jednak pamiętać, że gdy kontrola zadań jest wyłączona (jak w skryptach), catproces będzie działał asynchronicznie (tak, jakby zaczął się &).

Stéphane Chazelas
źródło
3
Dzięki! Innym sposobem na obejście tego jest (echo hi 2>&1 1>/dev/null) | cat.
Tavian Barnes
1
@TavianBarnes, dobry punkt, dzięki. Dodałem go do odpowiedzi w celu uzyskania kompletności. Działa również z grupą poleceń ( {echo...}|cat)
Stéphane Chazelas,