2011-01-11 3 views
6

Учитывая следующий пример ввода на STDIN:Возможно ли распространять STDIN на параллельные процессы?

foo 
bar bar 
baz 
=== 
qux 
bla 
=== 
def 
zzz yyy 

Можно ли разделить его на разделитель (в данном случае «===») и кормить его через стандартный ввод в команде работает параллельно?

Таким образом, пример входной сигнал выше, будет приводить в 3 параллельных процессах (например, команда называется do.sh), где каждый экземпляр получил часть данных на STDIN, как это:

do.sh (экземпляр 1) принимает это над STDIN:

foo 
bar bar 
baz 

do.sh (экземпляр 2) принимает это над STDIN:

qux 
bla 

do.sh (пример 3) принимает это более STDIN:

def 
zzz yyy 

Я полагаю, что-то, как это возможно с помощью xargs или GNU параллельно, но я не знаю, как.

ответ

10

GNU Parallel может сделать это с версии 20110205.

cat | parallel --pipe --recend '===\n' --rrs do_stuff 
2

В общем, нет. Одной из причин такой оценки является то, что стандартное чтение ввода-вывода из файлов, а не терминала, считывает блоки данных - байты BUFSIZ за раз, где BUFSIZ обычно имеет мощность 2, например 512 или более. Если данные находятся в файле, один процесс будет читать весь указанный файл - остальные ничего не увидели бы, если бы они разделили одно и то же открытое описание файла (аналогично файловому дескриптору, но несколько файловых дескрипторов могут совместно использовать одно и то же описание открытого файла и может быть в разных процессах), или будет читать весь тот же файл, если они не используют одно и то же описание открытого файла.

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

Ваш пример не показывает/не описывает, что произойдет, если бы было 37 разделов, разделенных маркером.

У меня есть программа самогон под названием tpipe, которое, как tee команды Unix, но он пишет копию (все) стандартного ввода для каждого из процессов, а также на стандартный вывод тоже по умолчанию. Это может быть подходящей основой для того, что вам нужно (оно, по крайней мере, охватывает часть управления процессом). Свяжитесь со мной, если вы хотите получить копию - см. Мой профиль.


Если вы используете Bash, вы можете использовать регулярные tee с подменой процесса для имитации tpipe. См. Это article для иллюстрации того, как.

Смотрите также SF 96245 для другой версии той же самой информации - плюс ссылку на программу под названием pee, которая очень похожа на tpipe (та же самая основная идея, немного отличается реализации в различных аспектах).

+0

Как 'tpipe' отличается от' pee'? –

+0

Я написал tpipe и раньше не слышал о мочах. Но меня не удивляет, что кто-то другой имел одно и то же основное требование и реализовал его. Я не уверен, что вы можете догадаться, как сложно искать «мочиться» через Google (даже «site: gnu.org pee» появляется спам)! Таким образом, без URL-адреса программного обеспечения я не могу сравнивать и не сравнивать вас. –

+0

http://serverfault.com/questions/96245/linux-debian-what-does-pee-in-moreutils-do показывает 'pee' в использовании и показывает, как вам не нужно' pee' в 'bash':' кошачий файл | tee> (command1> out1)> (command2> out2) ' –

1

Вы можете сделать это, используя named pipes. Именованные каналы позволяют обрабатывать стандартные трубопроводы в виде файлов. У вас может быть несколько именованных каналов, и ваши другие программы обрабатывают их.

Я не так хорошо знаком с именованными каналами, но я использовал их время от времени в таких ситуациях.