LINUX.ORG.RU

разделение потоков


0

0

Подскажите можно ли стандартным способом в linux-shell разделить потоки(cout и cerr) по процессам?

Т.е. чтобы поток вывода обрабатывался в одном процессе а поток ошибок в другом?

Требуется решение вида: ./command |1 ./cout_gandler |2 ./cerr_handler

Ответ на: комментарий от ansky

Засунь свои именованные пайпы в неименованные пайпы!

anonymous
()
Ответ на: комментарий от jerry_ru

Цитируем jerry_ru

linux-shell

Упс, подумал, что только с bash работаем.

zsh: $ command 2>>(./cerr_handler) | ./cout_handler

shahid ★★★★★
()
Ответ на: комментарий от shahid

> exec 3>&1

command 2>&1 >&3 3>&- | ./cerr_handler 3>&- | ./cout_gandler
exec 3>&-

Чуствую что это то что надо, только чет не могу воткнуть в магию... Можно пару коментариев?

а zsh это хорошо!

jerry_ru
() автор топика
Ответ на: комментарий от jerry_ru

Цитируем jerry_ru

Чуствую что это то что надо, только чет не могу воткнуть в магию... Можно пару коментариев?

Тут всё просто, хоть и не очевидно: вначале и в конце инициализируем дескриптор баша &3.

Затем присваем дескрипторам новые указатели указатели: stderr (&2) в stdout(&1) т.е. в первый пайп, а stdout в наш новый дескриптор.

Далее, запираем вывод &3 для последующей команды cerr_handler, и отпираем его уже перед cout_handler.

Ну и подметаем за собой в третей строке, освобождая дескриптор обратно ибо он тоже обычно используется самим башем.

shahid ★★★★★
()
Ответ на: комментарий от shahid

Чего-то не получается: скрипт test генерящий оба вывода:

echo «error out» 1>&2;echo «normal out»

./test 2>&1 1>&3 3>&- | grep err 1>err 3>&- | grep norm 1>norm

1. 'error out' перехватывается и обрабатывается правильно(заполняя файл err)

2. 'norm out' попадает в консоль, и никем не перхватывается(файл norm пуст)

Попробовал разные варианты не получается :(

"...и отпираем его уже перед cout_handler..." - помоему что-то тут не так - отпирание и запирание выглядит одинаково?

jerry_ru
() автор топика
Ответ на: комментарий от tailgunner

Понял намек.
для первого раза реализовал так:

splitter:
rm -f /tmp/$1_cerrf /tmp/$1_coutf
mkfifo /tmp/$1_cerrf /tmp/$1_coutf
cat /tmp/$1_coutf | $2 &
cat /tmp/$1_cerrf | $3 &
$1 1>/tmp/$1_coutf 2>/tmp/$1_cerrf
rm -f /tmp/$1_cerrf /tmp/$1_coutf

а запускается так:
./splitter ./test «grep norm» grep «err»

Вроде работает.

jerry_ru
() автор топика
Ответ на: комментарий от tailgunner

Ну кроме красоты еще: 1. все-таки таким образом мы гадим в систему. 2. сложно запустить два конвеера одновременно - надо генерить непересекающиеся файлы.

jerry_ru
() автор топика
Ответ на: комментарий от jerry_ru

Хм, действительно вылетает мимо пайпа. Страннах...

Голова уже не варит на ночь. Заюзай пока zsh - там вроде без изврата работает.

shahid ★★★★★
()
Ответ на: комментарий от jerry_ru

> Ну кроме красоты еще:

Ну, если ты так серьезно подходишь к вопросу, попробуй так:

($OUTPUT_GENERATOR | $STDOUT_CONSUMER) 2>&1 | $STDERR_CONSUMER

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

:) это было то, с чего я начинал - так не работает.

'cout' ловится, а 'cerr' идет мимо. Вот объяснение:
" - перенаправление действует только на ту команду в конвейере, где оно задано;" (c)

Так что при таком написании 'cerr' попадает в консоль когда происходит исполнение $OUTPUT_GENERATOR, а во время $STDOUT_CONSUMER 'cerr' уже пустой.

jerry_ru
() автор топика
Ответ на: комментарий от jerry_ru

> :) это было то, с чего я начинал - так не работает.

Хм, ты заставил меня самого попробовать - УМВР.

Так что при таком написании 'cerr' попадает в консоль когда происходит исполнение $OUTPUT_GENERATOR, а во время $STDOUT_CONSUMER 'cerr' уже пустой.

Ы? $OUTPUT_GENERATOR и $STDOUT_CONSUMER исполняются параллельно.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

>Ы? $OUTPUT_GENERATOR и $STDOUT_CONSUMER исполняются параллельно.

Паралельность - это был мой вопрос для следующей темы...

Но тем не менее твоё предложение не работает.

jerry_ru
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.