Раздвоение stdout

На самом деле это единственный раздел про unix на этом форуме

Модераторы: /dev/random, Модераторы разделов

Demonas666
Сообщения: 25
ОС: Debian GNU/Linux

Раздвоение stdout

Сообщение Demonas666 »

Здравствуйте уважаемые линуксоиды! ))

Подскажите пожалуйста, как бы раздвоить стандартный вывод? Ситуация примерно такая:
Есть приложение, которое выдаёт в stdout какой-то набор строк.
Я при помощи конвейра
program | egrep
получаю некий подсписок с нужным мне условием. Но мне нужно проверить два условия, то есть получить два разных списка из одного исходного. Таким образом приходится либо заново перезапускать программу, строящую исходный список, либо сначала выводить список в файл, а потом с ним работать. Как первое, так и второе - не эффективно с т.з. производительности. Имеются ли какие-то стандартные средства для разветвления stdout?
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Раздвоение stdout

Сообщение drBatty »

Demonas666 писал(а):
15.02.2010 00:02
Здравствуйте уважаемые линуксоиды! ))

Подскажите пожалуйста, как бы раздвоить стандартный вывод? Ситуация примерно такая:
Есть приложение, которое выдаёт в stdout какой-то набор строк.
Я при помощи конвейра
program | egrep
получаю некий подсписок с нужным мне условием. Но мне нужно проверить два условия, то есть получить два разных списка из одного исходного. Таким образом приходится либо заново перезапускать программу, строящую исходный список, либо сначала выводить список в файл, а потом с ним работать. Как первое, так и второе - не эффективно с т.з. производительности. Имеются ли какие-то стандартные средства для разветвления stdout?

у вас и так 2 потока:
/dev/stdout и /dev/stderr
по умолчанию программа выводит в первый обычный вывод, а во второй - ошибки. Однако вы можете перенаправить любой из потоков куда угодно (второй на первый а первый в файл например).

Если вам нужно и в правду раздвоить, используйте tee - она отправит ст. вывод в стандартный вывод и одновременно в файл.

ЗЫЖ а есть ещё третий поток - стандартный лог. но он используется очень редко при работе в консоли (его используют в основном демоны).
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Demonas666
Сообщения: 25
ОС: Debian GNU/Linux

Re: Раздвоение stdout

Сообщение Demonas666 »

Либо Вы меня не поняли, либо я Вас. У меня программа всё выводит в stdout, и нужно этот вывод дважды параллельно обработать egrep'ом. В файл мне выводить не нужно, мне нужно, чтобы оба результата были в стандартном выводе, по очереди. Каждый из этих выводов будет перенаправляться через конвейер в свою программу.
Спасибо сказали:
Аватара пользователя
diesel
Бывший модератор
Сообщения: 5989
ОС: OS X, openSuSE, ROSA, Debian

Re: Раздвоение stdout

Сообщение diesel »

Кто идет на Unix-way первый пост на странице
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Раздвоение stdout

Сообщение drBatty »

Demonas666 писал(а):
15.02.2010 01:35
В файл мне выводить не нужно, мне нужно, чтобы оба результата были в стандартном выводе, по очереди. Каждый из этих выводов будет перенаправляться через конвейер в свою программу.

diesel писал(а):
15.02.2010 02:53
Кто идет на Unix-way первый пост на странице

я так пробовал - выяснилось, что в отличие от моего компа, мой мозг не многозадачный. это жутко неудобно.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Demonas666
Сообщения: 25
ОС: Debian GNU/Linux

Re: Раздвоение stdout

Сообщение Demonas666 »

diesel писал(а):
15.02.2010 02:53
Кто идет на Unix-way первый пост на странице

Спасибо, как раз то, что нужно! Поиском пользовался, но тема довольно неопределённо звучит, так что не нашёл. Мне почему-то казалось, что должна быть такая возможность на уровне шелла :)
Тему можно закрыть.
Спасибо сказали:
Аватара пользователя
Denjs
Сообщения: 1685
ОС: SuSe 10.2

Re: Раздвоение stdout

Сообщение Denjs »

почему бы не отправить stdout в файл или переменную а потом 2 раза печатать это на вход в grep ?

т.е. либо так

Код: Выделить всё

 ваша_программа >> file
 cat file | grep условие1
 cat file | grep условие2

либо так

Код: Выделить всё

 stdoutvar= $(ваша_программа)
 echo $stdoutvar | grep условие1
 echo $stdoutvar | grep условие2

?
QDroid - Среда исполнения и фреймворк для QtScript.
OTPD - Открытые драйвера промышленных принтеров чеков и этикеток (кроссплатформенная подсистема печати).
Спасибо сказали:
Demonas666
Сообщения: 25
ОС: Debian GNU/Linux

Re: Раздвоение stdout

Сообщение Demonas666 »

Denjs
Не выгодно с точки зрения производительности. Это вычислительная система, бездисковый кластер. Не хотелось бы забивать память переменными сумасшедшей длинны, а хотелось бы сразу на конвейере обрабатывать вывод, не сохраняя его. Ведь конвейер - синхронный, не буферирует полностью вывод.
Спасибо сказали:
BIgAndy
Сообщения: 1923

Re: Раздвоение stdout

Сообщение BIgAndy »

А как насчет tee?
Спасибо сказали:
Аватара пользователя
Black
Сообщения: 1104
ОС: ArchLinux

Re: Раздвоение stdout

Сообщение Black »

diesel писал(а):
15.02.2010 02:53
Кто идет на Unix-way первый пост на странице

Спасибо, не знал про такое. Полезная штука.
Я обычно загоняю в переменную, а потом из неё выгрепываю всё, что нужно, по очереди.
Компьютер служит для решения тех проблем, которых до изобретения компьютера не существовало
Спасибо сказали:
smaharbA
Сообщения: 229
ОС: Windows Vista

Re: Раздвоение stdout

Сообщение smaharbA »

(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 ?
Я конечно далек от мысли...(с)
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Раздвоение stdout

Сообщение drBatty »

Demonas666 писал(а):
15.02.2010 01:35
Либо Вы меня не поняли, либо я Вас. У меня программа всё выводит в stdout, и нужно этот вывод дважды параллельно обработать egrep'ом.

такие задачи встречались и у меня: я загоняю один ввод в stderr, а второй - в файл. если мне хочется смотреть на всё сразу - открываю вторую консоль, и tail -f.

Demonas666 писал(а):
15.02.2010 14:53
бездисковый кластер.

а... это меняет дело. мне по любому надо загонять в файл, т.к. мои скрипты обычно работают автономно, и пишут вывод в лог.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Demonas666
Сообщения: 25
ОС: Debian GNU/Linux

Re: Раздвоение stdout

Сообщение Demonas666 »

drBatty писал(а):
15.02.2010 20:22
а... это меняет дело. мне по любому надо загонять в файл, т.к. мои скрипты обычно работают автономно, и пишут вывод в лог.

Этот тоже в автономе практически, просто в зависимости от вывода запускается та или иная программа, с этим самым выводом в качестве входных данных :)
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Раздвоение stdout

Сообщение drBatty »

Demonas666 писал(а):
16.02.2010 00:46
Этот тоже в автономе практически, просто в зависимости от вывода запускается та или иная программа, с этим самым выводом в качестве входных данных

а может можно создать (не)именованный канал, и направить туда stderr?
вроде:
prog1 2>pipe | prog2; prog3 < pipe
только я так никогда не делал...
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Demonas666
Сообщения: 25
ОС: Debian GNU/Linux

Re: Раздвоение stdout

Сообщение Demonas666 »

drBatty писал(а):
16.02.2010 00:54
а может можно создать (не)именованный канал, и направить туда stderr?

К сожалению, stderr уже занят...
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Раздвоение stdout

Сообщение drBatty »

Demonas666 писал(а):
16.02.2010 01:27
К сожалению, stderr уже занят...

stdlog?

PS: для параллельности наверное надо поставить & вместо точки с запятой. (в моём примере)
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Demonas666
Сообщения: 25
ОС: Debian GNU/Linux

Re: Раздвоение stdout

Сообщение Demonas666 »

drBatty писал(а):
16.02.2010 01:37
Demonas666 писал(а):
16.02.2010 01:27
К сожалению, stderr уже занят...

stdlog?

PS: для параллельности наверное надо поставить & вместо точки с запятой. (в моём примере)


С stdlog не работал, как с ним в Си работать? В любом случае, проблема решена, и решена без переписывания кода, что есть замечательно :)
Спасибо сказали:
Аватара пользователя
t.t
Бывший модератор
Сообщения: 7390
Статус: думающий о вечном
ОС: Debian, LMDE

Re: Раздвоение stdout

Сообщение t.t »

smaharbA писал(а):
15.02.2010 18:59
(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
Не советую так экспериментировать со stderr. В нём ведь окажутся и сообщения об ошибках первоначальной команды. Лучше уж создать дополнительный поток вывода и дублировать в него. Но даже этот вариант -- излишнее усложнение по сравнению с уже существующим решением, на которое выше дана ссылка (pee из пакета moreutils).
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
Спасибо сказали:
Аватара пользователя
sgfault
Сообщения: 586
Статус: -

Re: Раздвоение stdout

Сообщение sgfault »

t.t писал(а):
17.02.2010 13:23
Но даже этот вариант -- излишнее усложнение по сравнению с уже существующим решением, на которое выше дана ссылка (pee из пакета moreutils).

Если `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`) ? :-)
Спасибо сказали:
Аватара пользователя
/dev/random
Администратор
Сообщения: 5404
ОС: Gentoo

Re: Раздвоение stdout

Сообщение /dev/random »

[offtop]
Между прочим, с этим pee у меня один забавный казус вышел. Когда я встречаю незнакомую команду, которая у меня отсутствует, я в первую очередь набираю в гугле как в командной строке: man команда и там уже смотрю, что она из себя представляет. Когда я впервые наткнулся на команду pee, то, не задумываясь, ввёл в гугле: man pee. Кто знает английский, поймёт, что мне выдал гугл.
[offtop]
Спасибо сказали:
Lan4
Сообщения: 339
Статус: hikki
ОС: Arch

Re: Раздвоение stdout

Сообщение Lan4 »

/dev/random писал(а):
19.02.2010 21:50
[offtop]
Между прочим, с этим pee у меня один забавный казус вышел. Когда я встречаю незнакомую команду, которая у меня отсутствует, я в первую очередь набираю в гугле как в командной строке: man команда и там уже смотрю, что она из себя представляет. Когда я впервые наткнулся на команду pee, то, не задумываясь, ввёл в гугле: man pee. Кто знает английский, поймёт, что мне выдал гугл.
[offtop]

:D гугл не понял, что от него хотели =))))
Спасибо сказали:
Аватара пользователя
sash-kan
Администратор
Сообщения: 13939
Статус: oel ngati kameie
ОС: GNU

Re: Раздвоение stdout

Сообщение sash-kan »

гугль прекрасно всё понял.
Писать безграмотно - значит посягать на время людей, к которым мы адресуемся, а потому совершенно недопустимо в правильно организованном обществе. © Щерба Л. В., 1957
при сбоях форума см.блог
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Раздвоение stdout

Сообщение drBatty »

/dev/random писал(а):
19.02.2010 21:50
Кто знает английский, поймёт, что мне выдал гугл.

кто не знает - может повторить :)
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
t.t
Бывший модератор
Сообщения: 7390
Статус: думающий о вечном
ОС: Debian, LMDE

Re: Раздвоение stdout

Сообщение t.t »

drBatty писал(а):
20.02.2010 10:05
/dev/random писал(а):
19.02.2010 21:50
Кто знает английский, поймёт, что мне выдал гугл.
кто не знает - может повторить :)
Ничего себе флешмобчик.
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
Спасибо сказали:
arto
Сообщения: 7

Re: Раздвоение stdout

Сообщение arto »

zsh# proc | tee >( grep aaa > aaa.out ) >( grep bbb > bbb.out ) > /dev/null
Спасибо сказали:
Аватара пользователя
sgfault
Сообщения: 586
Статус: -

Re: Раздвоение stdout

Сообщение sgfault »

arto писал(а):
24.02.2010 15:18
zsh# proc | tee >( grep aaa > aaa.out ) >( grep bbb > bbb.out ) > /dev/null

Но ведь ваш пример - то же самое, что и приведенный выше

Код: Выделить всё

( 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.. :unsure:
Спасибо сказали: