Можно ли перенаправить вывод команды более чем в одну команду?


21

Насколько я знаю, я могу использовать команду tee, чтобы разделить стандартный вывод на экран и другие файлы:

command -option1 -option2 argument | tee file1 file2 file3 

Можно ли перенаправить вывод в команды вместо файлов, используя tee, чтобы я теоретически мог создать цепочку команд?


3
Объясните, что вы подразумеваете под «выходным сигналом», и опишите, что вы подразумеваете под созданием «сети команд».
— Янис

В Linux каждая команда имеет один вход и два выхода. они помечены 0 (для ввода), 1 (для вывода) и 2 (для вывода ошибки). Я думал о 1, когда я сказал «выходной сигнал», потому что я прочитал, что команда tee разделяет только выходные данные, помеченные 1. Когда я сказал «сеть команд», я не был очень техническим, я не уверен, как сеть определена правильно из с математической точки зрения, но я просто думал о дереве команд, типологически говоря, так что некоторые команды могут быть родителями более чем одной дочерней команды.
— Абдул Аль Хазред

Спасибо за ваше разъяснение. Пожалуйста, не используйте слово «сигнал», так как оно имеет определенное значение в Unix, и в этом контексте термин вводит в заблуждение. Еще раз спасибо.
— Янис

В командной строке введите man -k signal, чтобы узнать особое значение этого ключевого понятия в UNIX и Linux. man kill будет хорошей страницей для начала.
— Роб

Кроме того, многие люди называют stdin stdout и stderr входными или выходными «потоками». Есть как небольшие реки данных, следовательно, поток. Вы были правы, когда ухватились за слово, чтобы описать их коллективно, но сигнал - просто неправильное слово.
— Роб

Ответы:


25

Вы можете использовать именованные каналы ( http://linux.die.net/man/1/mkfifo ) в командной строке teeи иметь команды, читающие на именованных каналах.

mkfifo /tmp/data0 /tmp/data1 /tmp/data2
cmd0 < /tmp/data0 & cmd1 < /tmp/data1 & cmd2 < /tmp/data2 &
command -option1 -option2 argument | tee /tmp/data0 /tmp/data1 /tmp/data2

Когда commandзакончится, teeзакроет именованные каналы, которые будут сигнализировать EOF (чтение 0 байтов) на каждом из /tmp/dataNкоторых обычно завершит cmdNпроцессы. Реальный пример:

$ mkfifo /tmp/data0 /tmp/data1 /tmp/data2
$ wc -l < /tmp/data0 & wc -w < /tmp/data1 & wc -c < /tmp/data2 &
$ tee /tmp/data0 /tmp/data1 /tmp/data2 < /etc/passwd >/dev/null
$ 61
1974
37

Из-за фоновых процессов оболочка вернула приглашение перед выходом программы. Все три экземпляра wcпрекращаются нормально.


1
В bash вы можете безопасно печатать через /tmp/data/{0,1,2}. Опять же, в bash вы можете использовать процесс подстановки и mkfifoполностью пропустить
— Тобиас Кинцлер

2
Возможно, вы захотите изменить / dev / data0 на / tmp / data0. Кроме того, спасибо за ответ на вопрос в неявной форме. Это более полезно, чем предполагать, что все используют bash.
— Абонет

15

Если я правильно понимаю, вы ищете эквивалент tee file1 file2 file3, но вместо того, чтобы записывать одни и те же данные в три файла file1, file2и file3вы хотите разделить одни и те же данные на три команды cmd1, cmd2и cmd3, т.е.

… | ??? cmd1 cmd2 cmd3

должно быть эквивалентно

… | cmd1 &
… | cmd2 &
… | cmd3 &

за исключением того, …что будет выполнено только один раз.

Есть два способа сделать это.

Ksh93, bash и zsh поддерживают процесс подстановки . Это обобщение каналов, которое позволяет аргументу команды быть файлом, который при записи в него передает данные в качестве входных данных для команды (также существует вариант ввода, который при чтении из него получает данные, выводимые командой) , То есть,

echo hello | tee >(cmd1)

печатает helloна стандартный вывод и дополнительно работает cmd1с helloвводом.

Так, например, если вы хотите дублировать ввод somecommandи передать его обоим cmd1и cmd2, вы можете использовать

somecommand | tee >(cmd1) | cmd2

Если ваша оболочка не поддерживает подстановку процессов, вы можете использовать именованные каналы. Посмотрите ответ Арсеге о том, как это работает. Именованные каналы менее удобны, чем подстановка процессов, потому что их нужно создавать и удалять, а также запускать и синхронизировать процессы вручную. Их преимущество в том, что они полностью переносимы, в то время как не все оболочки поддерживают процессные замены. Они также могут использоваться в сценариях, отличных от тех, для которых предназначена замена процесса.

Под капотом в некоторых системах для подстановки процессов используются именованные каналы. Однако в большинстве систем он использует именованные файлы, представляющие файловые дескрипторы .


5
Смотрите также peeиз moreutils.
— Стефан Шазелас

Обратите внимание, что замена процесса была введена ksh88.
— Стефан Шазелас


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.