LINUX.ORG.RU

Передать STDOUT параллельно на два процесса

 ,


0

2

Всем привет! Хочу, выстроить примерно такую команду:

php parent.php | ( php child.php & php child.php; )

При этом нужно, чтобы standard output, генерируемый parent.php, уходил в оба child.php (одинаковый). И чтобы эти child.php работали параллельно. Пробовал и фигурные скобки писать, и разные комбинации & и ;. Всегда сталкиваюсь с тем, что либо процессы child.php работают последовательно (один после другого), либо standart output из parent.php приходит только в один из них.

То, что я хочу, вообще возможно составить?



Последнее исправление: Novascriptum (всего исправлений: 1)

Тебе нужны named pipe.
Как-то так. Но это не точно.
$ mkfifo a
$ mkfifo b
$ php child.php < a &
$ php child.php < b &
$ php parent.php | tee a b

urxvt ★★★★★
()

Как-то можно через tee. Сейчас накопаю.

crutch_master ★★★★★
()

https://stackoverflow.com/questions/60942/how-can-i-send-the-stdout-of-one-pr...

Usually you would use tee to redirect output to multiple files, but using >(...) you can redirect to another process. So, in general,

$ proc1 | tee >(proc2) ... >(procN-1) >(procN) >/dev/null

Например

$ echo 123 | tee >(tr 1 a) >(tr 1 b)
123
a23
b23

crutch_master ★★★★★
()
Последнее исправление: crutch_master (всего исправлений: 1)
Ответ на: комментарий от crutch_master

Спасибо, заработало почти что как надо. Только что-то виснет. Поясню примером. Написал простенький скрипт numbers.php, который выводит 10 чисел:

for($i = 1; $i <= 10; $i++){
    echo "$i\n";
}

Также написал child.php, который читает построчно standard input и ждём между строками некоторое время:

$procId = getmypid();
while($line = fgets(\STDIN)){
    $interval = mt_rand(1000, 300000);
    usleep($interval);
    echo "$procId: $line";
}

Запускаю цепочку, всё работает:

[bin]$ php numbers.php | php child.php
8355: 1
8355: 2
8355: 3
8355: 4
8355: 5
8355: 6
8355: 7
8355: 8
8355: 9
8355: 10
[bin]$

Теперь добавляем tee, и выполнение зависает, как будто чего-то ещё ждём от скрипта numbers.php, но он не даёт (не закрывает поток):

[bin]$ php numbers.php | tee >(php child.php) >(php child.php) >/dev/null
[bin]$ 8484: 1
8483: 1
8483: 2
8484: 2
8483: 3
8483: 4
8484: 3
8483: 5
8484: 4
8484: 5
8483: 6
8484: 6
8483: 7
8483: 8
8484: 7
8483: 9
8484: 8
8484: 9
8483: 10
8484: 10


...и висит, висит. Где-то надо что-то принудительно завершить?

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

Он не висит. Жамкни enter, там просто фоновый процесс шел и он не показывает приветствие. Проверил, все процессы дохнут.

crutch_master ★★★★★
()
Последнее исправление: crutch_master (всего исправлений: 1)
Ответ на: комментарий от Novascriptum

Сделай как-нибудь через субшел типа

x=$(php numbers.php | tee >(php child.php) >(php child.php) >/dev/null)
Или прямее, я лучше не умею.

crutch_master ★★★★★
()

@moreutils

NAME   
       pee - tee standard input to pipes

SYNOPSIS
       pee [["command"...]]

DESCRIPTION
       pee is like tee but for pipes. Each command is run and fed a copy of the standard input. The output of all commands is sent to stdout.
YAR ★★★★★
()
Ответ на: комментарий от no-such-file

Мне надо из одного php-процесса передавать STDOUT на два других (тоже php), которые должны эти данные обрабатывать в параллельном режиме (так как отсылают их по сети в разные точки). Поэтому попробую через proc_open запустить «tee», который распределит поток между двумя другими процессами. Как попробую, отпишусь о результате.

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

может быть тебе нужно что-то с гарантированной доставкой? MQ какое-то? Ну, типа RabbitMQ/Kafka…

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