Тройник только для команд, а не для стандартного вывода

Я уже знаю, как использовать tee с подстановкой процесса для отправки вывода различным командам, и stdout, например

command0 | tee >(command1) >(command2)

С приведенной выше строкой стандартный вывод будет состоять из чередующихся строк command0, command1 и command2.

Есть ли способ предотвратить запись tee в стандартный вывод без удаления вывода каких-либо команд, которым он передает? Итак, для приведенного выше примера, чтобы стандартный вывод имел вывод только из command1 и command2? Большинство ответов, касающихся teeing без stdout, записываются только непосредственно в файлы и рекомендуют использовать что-то вроде этого:

command0 | tee file1 file2 >/dev/null

Но с заменой процесса это также поглотит весь вывод других команд.

command0 | tee >(command1) >(command2) >/dev/null

Есть ли какой-нибудь способ сказать tee не печатать на стандартный вывод или использовать вывод только напрямую из tee?


person Zoey Hewll    schedule 05.04.2019    source источник


Ответы (2)


Я видел комментарий и ответ, который использует дополнительный >, но на самом деле не объясняет, почему он делает то, что делает. Похоже, что он перенаправляет вывод куда-то, но все, что я могу сказать, это то, что он делает то, что я ищу. Это работает:

command0 | tee > >(command1) >(command2)
command0 | tee >(command1) > >(command2)

кажется, не имеет значения, где находится лишний >, если он стоит перед хотя бы одним из аргументов tee. Так что это не сработает:

command0 | tee >(command1) >(command2) >

Не зная, как это называется, и без дальнейших зацепок, я не могу дальше объяснять.

person Zoey Hewll    schedule 05.04.2019
comment
> >(foo) перенаправляет на замену процесса >(foo). Замена процесса включает замену >(foo) на путь к файлу, представляющему стандартный ввод foo, поэтому думайте об этом как о tee > /some/stdin1 /some/stdin2 или, что то же самое, tee /some/stdin2 > /some/stdin1, что должно прояснить, что происходит. - person muru; 05.04.2019
comment
Это заставляет меня думать, что он отправит дополнительную копию конвейерного вывода в процесс, но я знаю эмпирически, что это не так. Связанная документация, похоже, нигде не упоминает этот шаблон. - person Zoey Hewll; 05.04.2019
comment
О, вы хотите сказать, что >(foo) больше не аргумент для tee в случае > >(foo), а просто перенаправление в середине команды? - person Zoey Hewll; 05.04.2019
comment
Да, > >(foo) — это перенаправление в середине команды. Просто подумайте о >(foo) как о пути к файлу (специальному файлу, но, тем не менее, файлу). - person muru; 05.04.2019
comment
Я только что понял, я не уверен, как я пришел к выводу, что >/dev/null терпит неудачу в этом случае, потому что это не так. Он захватывает только вывод из tee stdout, а не процессов, которым он отправляет вывод. - person Zoey Hewll; 05.04.2019

Попробуй это:

( command0 | tee >(command1 1>&3 ) | command2 ) 3>&1

Он перенаправляет стандартный вывод команды1 в канал 3, так что команда2 видит только исходный источник. В конце вы снова перенаправляете канал 3 на стандартный вывод.

Используйте это, чтобы проверить это:

( echo test | tee >( sed 's/^/1 /' >&3 )  | sed 's/^/2 /' ) 3>&1

Вывод неупорядочен и в моем случае:

2 test
1 test
person Wiimm    schedule 05.04.2019