Раздвоение stdout
Модераторы: /dev/random, Модераторы разделов
-
- Сообщения: 25
- ОС: Debian GNU/Linux
Раздвоение stdout
Здравствуйте уважаемые линуксоиды! ))
Подскажите пожалуйста, как бы раздвоить стандартный вывод? Ситуация примерно такая:
Есть приложение, которое выдаёт в stdout какой-то набор строк.
Я при помощи конвейра
program | egrep
получаю некий подсписок с нужным мне условием. Но мне нужно проверить два условия, то есть получить два разных списка из одного исходного. Таким образом приходится либо заново перезапускать программу, строящую исходный список, либо сначала выводить список в файл, а потом с ним работать. Как первое, так и второе - не эффективно с т.з. производительности. Имеются ли какие-то стандартные средства для разветвления stdout?
Подскажите пожалуйста, как бы раздвоить стандартный вывод? Ситуация примерно такая:
Есть приложение, которое выдаёт в stdout какой-то набор строк.
Я при помощи конвейра
program | egrep
получаю некий подсписок с нужным мне условием. Но мне нужно проверить два условия, то есть получить два разных списка из одного исходного. Таким образом приходится либо заново перезапускать программу, строящую исходный список, либо сначала выводить список в файл, а потом с ним работать. Как первое, так и второе - не эффективно с т.з. производительности. Имеются ли какие-то стандартные средства для разветвления stdout?
-
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
Re: Раздвоение stdout
Demonas666 писал(а): ↑15.02.2010 00:02Здравствуйте уважаемые линуксоиды! ))
Подскажите пожалуйста, как бы раздвоить стандартный вывод? Ситуация примерно такая:
Есть приложение, которое выдаёт в stdout какой-то набор строк.
Я при помощи конвейра
program | egrep
получаю некий подсписок с нужным мне условием. Но мне нужно проверить два условия, то есть получить два разных списка из одного исходного. Таким образом приходится либо заново перезапускать программу, строящую исходный список, либо сначала выводить список в файл, а потом с ним работать. Как первое, так и второе - не эффективно с т.з. производительности. Имеются ли какие-то стандартные средства для разветвления stdout?
у вас и так 2 потока:
/dev/stdout и /dev/stderr
по умолчанию программа выводит в первый обычный вывод, а во второй - ошибки. Однако вы можете перенаправить любой из потоков куда угодно (второй на первый а первый в файл например).
Если вам нужно и в правду раздвоить, используйте tee - она отправит ст. вывод в стандартный вывод и одновременно в файл.
ЗЫЖ а есть ещё третий поток - стандартный лог. но он используется очень редко при работе в консоли (его используют в основном демоны).
-
- Сообщения: 25
- ОС: Debian GNU/Linux
Re: Раздвоение stdout
Либо Вы меня не поняли, либо я Вас. У меня программа всё выводит в stdout, и нужно этот вывод дважды параллельно обработать egrep'ом. В файл мне выводить не нужно, мне нужно, чтобы оба результата были в стандартном выводе, по очереди. Каждый из этих выводов будет перенаправляться через конвейер в свою программу.
-
- Бывший модератор
- Сообщения: 5989
- ОС: OS X, openSuSE, ROSA, Debian
Re: Раздвоение stdout
Кто идет на Unix-way первый пост на странице
-
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
Re: Раздвоение stdout
Demonas666 писал(а): ↑15.02.2010 01:35В файл мне выводить не нужно, мне нужно, чтобы оба результата были в стандартном выводе, по очереди. Каждый из этих выводов будет перенаправляться через конвейер в свою программу.
я так пробовал - выяснилось, что в отличие от моего компа, мой мозг не многозадачный. это жутко неудобно.
-
- Сообщения: 25
- ОС: Debian GNU/Linux
Re: Раздвоение stdout
Спасибо, как раз то, что нужно! Поиском пользовался, но тема довольно неопределённо звучит, так что не нашёл. Мне почему-то казалось, что должна быть такая возможность на уровне шелла

Тему можно закрыть.
-
- Сообщения: 1685
- ОС: SuSe 10.2
Re: Раздвоение stdout
почему бы не отправить stdout в файл или переменную а потом 2 раза печатать это на вход в grep ?
т.е. либо так
либо так
?
т.е. либо так
Код: Выделить всё
ваша_программа >> file
cat file | grep условие1
cat file | grep условие2
либо так
Код: Выделить всё
stdoutvar= $(ваша_программа)
echo $stdoutvar | grep условие1
echo $stdoutvar | grep условие2
?
-
- Сообщения: 25
- ОС: Debian GNU/Linux
Re: Раздвоение stdout
Denjs
Не выгодно с точки зрения производительности. Это вычислительная система, бездисковый кластер. Не хотелось бы забивать память переменными сумасшедшей длинны, а хотелось бы сразу на конвейере обрабатывать вывод, не сохраняя его. Ведь конвейер - синхронный, не буферирует полностью вывод.
Не выгодно с точки зрения производительности. Это вычислительная система, бездисковый кластер. Не хотелось бы забивать память переменными сумасшедшей длинны, а хотелось бы сразу на конвейере обрабатывать вывод, не сохраняя его. Ведь конвейер - синхронный, не буферирует полностью вывод.
-
- Сообщения: 1104
- ОС: ArchLinux
Re: Раздвоение stdout
Спасибо, не знал про такое. Полезная штука.
Я обычно загоняю в переменную, а потом из неё выгрепываю всё, что нужно, по очереди.
Компьютер служит для решения тех проблем, которых до изобретения компьютера не существовало
-
- Сообщения: 229
- ОС: Windows Vista
Re: Раздвоение stdout
(echo -e '123\n234' | tee /dev/stderr | sed 's/^/a/g' > one 2> /dev/null) 2>&1 | sed 's/^/b/g' > two; cat one; cat two
так tee ? или fifo и exec ?
так tee ? или fifo и exec ?
Я конечно далек от мысли...(с)
-
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
Re: Раздвоение stdout
Demonas666 писал(а): ↑15.02.2010 01:35Либо Вы меня не поняли, либо я Вас. У меня программа всё выводит в stdout, и нужно этот вывод дважды параллельно обработать egrep'ом.
такие задачи встречались и у меня: я загоняю один ввод в stderr, а второй - в файл. если мне хочется смотреть на всё сразу - открываю вторую консоль, и tail -f.
а... это меняет дело. мне по любому надо загонять в файл, т.к. мои скрипты обычно работают автономно, и пишут вывод в лог.
-
- Сообщения: 25
- ОС: Debian GNU/Linux
Re: Раздвоение stdout
Этот тоже в автономе практически, просто в зависимости от вывода запускается та или иная программа, с этим самым выводом в качестве входных данных

-
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
Re: Раздвоение stdout
Demonas666 писал(а): ↑16.02.2010 00:46Этот тоже в автономе практически, просто в зависимости от вывода запускается та или иная программа, с этим самым выводом в качестве входных данных
а может можно создать (не)именованный канал, и направить туда stderr?
вроде:
prog1 2>pipe | prog2; prog3 < pipe
только я так никогда не делал...
-
- Сообщения: 25
- ОС: Debian GNU/Linux
-
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
Re: Раздвоение stdout
stdlog?
PS: для параллельности наверное надо поставить & вместо точки с запятой. (в моём примере)
-
- Сообщения: 25
- ОС: Debian GNU/Linux
Re: Раздвоение stdout
-
- Бывший модератор
- Сообщения: 7390
- Статус: думающий о вечном
- ОС: Debian, LMDE
Re: Раздвоение stdout
Не советую так экспериментировать со stderr. В нём ведь окажутся и сообщения об ошибках первоначальной команды. Лучше уж создать дополнительный поток вывода и дублировать в него. Но даже этот вариант -- излишнее усложнение по сравнению с уже существующим решением, на которое выше дана ссылка (pee из пакета moreutils).
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
Спасибо сказали:
-
- Сообщения: 586
- Статус: -
Re: Раздвоение stdout
Если `pee` есть :-) Но мне очень интересно решение с помощью FIFO. Я смог придумать только такое
Код: Выделить всё
#cat ~/tmp/cr.txt
A B
B C
C
D C
E
Код: Выделить всё
#( exec 6>&1; cat ~/tmp/cr.txt | tee >(grep -e'C' >>/dev/fd/6) | grep -e'B' >>/dev/fd/6; exec 6>&- )
B C <-- выборка по 'C'
C <-- выборка по 'C'
D C <-- выборка по 'C'
A B <---- выборка по 'B',
B C <---- выборка по 'B',
но, интересно, можно ли сделать, заменив process substitution на обычное перенаправление в /dev/fd, и можно ли сделать без process substitution, и можно ли сделать без изменения дескрипторов родительского процесса (без `exec`) ? :-)
-
- Администратор
- Сообщения: 5404
- ОС: Gentoo
Re: Раздвоение stdout
[offtop]
Между прочим, с этим pee у меня один забавный казус вышел. Когда я встречаю незнакомую команду, которая у меня отсутствует, я в первую очередь набираю в гугле как в командной строке: man команда и там уже смотрю, что она из себя представляет. Когда я впервые наткнулся на команду pee, то, не задумываясь, ввёл в гугле: man pee. Кто знает английский, поймёт, что мне выдал гугл.
[offtop]
Между прочим, с этим pee у меня один забавный казус вышел. Когда я встречаю незнакомую команду, которая у меня отсутствует, я в первую очередь набираю в гугле как в командной строке: man команда и там уже смотрю, что она из себя представляет. Когда я впервые наткнулся на команду pee, то, не задумываясь, ввёл в гугле: man pee. Кто знает английский, поймёт, что мне выдал гугл.
[offtop]
-
- Сообщения: 339
- Статус: hikki
- ОС: Arch
Re: Раздвоение stdout
/dev/random писал(а): ↑19.02.2010 21:50[offtop]
Между прочим, с этим pee у меня один забавный казус вышел. Когда я встречаю незнакомую команду, которая у меня отсутствует, я в первую очередь набираю в гугле как в командной строке: man команда и там уже смотрю, что она из себя представляет. Когда я впервые наткнулся на команду pee, то, не задумываясь, ввёл в гугле: man pee. Кто знает английский, поймёт, что мне выдал гугл.
[offtop]

Blog: hikki-tech
-
- Администратор
- Сообщения: 13939
- Статус: oel ngati kameie
- ОС: GNU
Re: Раздвоение stdout
гугль прекрасно всё понял.
Писать безграмотно - значит посягать на время людей, к которым мы адресуемся, а потому совершенно недопустимо в правильно организованном обществе. © Щерба Л. В., 1957
при сбоях форума см.блог
при сбоях форума см.блог
-
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
Re: Раздвоение stdout
кто не знает - может повторить

-
- Бывший модератор
- Сообщения: 7390
- Статус: думающий о вечном
- ОС: Debian, LMDE
Re: Раздвоение stdout
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
-
- Сообщения: 7
Re: Раздвоение stdout
zsh# proc | tee >( grep aaa > aaa.out ) >( grep bbb > bbb.out ) > /dev/null
-
- Сообщения: 586
- Статус: -
Re: Раздвоение stdout
Но ведь ваш пример - то же самое, что и приведенный выше
Код: Выделить всё
( exec 6>&1; cat ~/tmp/cr.txt | tee >(grep -e'C' >>/dev/fd/6) | grep -e'B' >>/dev/fd/6; exec 6>&- )
только вывод собирается не в одном месте (/dev/fd/6, в котором открыт stdout), а в направляется в два разных (./aaa.out и ./bbb.out). Все тот же process substitution..
