Как я могу пайп только stderr в zsh?

18

В Баш:

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

Пока в зш

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

Есть ли способ передать только стандартную ошибку при перенаправлении стандарта?

Тавиан Барнс
источник

Ответы:

22

С zsh и включенной mult_iosопцией (по умолчанию), в:

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

The 1> /dev/null | catрассматривается как многократное перенаправление echos-stdout.

Таким образом echo, stdout теперь перенаправляется на оба /dev/nullканала и на канал cat(как при использовании tee).

Чтобы отменить это многократное перенаправление, вы можете сделать:

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

То есть закрытие стандартного вывода (отмена трубопровода) перед перенаправлением на /dev/null

Или используйте группу команд или подоболочку, например:

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

Таким образом, стандартный echoвывод перенаправляется только один раз (перенаправление канала применяется к группе / подоболочке и наследуется echo).

Или вы можете multiosполностью отключить :

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

В качестве альтернативы вы можете использовать замену процесса вместо канала:

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

Однако помните, что когда управление заданиями отключено (как в сценариях), catпроцесс будет выполняться асинхронно (как если бы он был запущен &).

Стефан Шазелас
источник
3
Благодарность! Еще один способ обойти это (echo hi 2>&1 1>/dev/null) | cat.
Тавиан Барнс
1
@TavianBarnes, хорошая мысль, спасибо. Я добавил это к ответу для полноты. Он также работает с командой group ( {echo...}|cat)
Стефан Шазелас