Термин для того, что вы пытаетесь достичь, означает мультиплексирование .
Это можно сделать довольно легко в bash, но для этого нужны некоторые более продвинутые функции bash.
Я создал сценарий на основе вашего, который, я думаю, делает то, что вы пытаетесь выполнить. Я объясню это ниже.
#!/bin/bash
manager() {
while IFS= read -r line; do
echo "manager[$1:$BASHPID]: $line"
done
}
fds=()
for (( i=0; i<5; i++ )); do
exec {fd}> >(manager $i)
fds+=( $fd )
done
while IFS= read -r line; do
echo "master: $line"
for fd in "${fds[@]}"; do
printf -- '%s\n' "$line" >&$fd
done
done
managerэто функция bash, которая просто читает из STDIN и записывает свой идентификатор и строку в STDOUT. Мы используем $BASHPIDвместо $$as $$не обновляется для подоболочек (это то, что мы будем использовать для запуска manager.
fdsявляется массивом, который будет содержать файловые дескрипторы, указывающие на каналы STDIN различных managerпорожденных объектов .
Затем мы проходим цикл и создаем 5 процессов менеджера. Я использую for (( ))синтаксис вместо того, как вы это делали, потому что он чище. Это зависит от bash, но некоторые вещи, которые выполняет этот скрипт, зависят от bash, поэтому вполне могут пройти весь путь.
Далее мы доберемся до exec {fd}> >(manager $i). Это делает еще несколько вещей, связанных с bash.
Первый из которых есть {fd}>. Это захватывает следующий доступный дескриптор файла на или после числа 10, открывает канал с записывающей стороной канала, назначенной этому дескриптору файла, и назначает номер дескриптора файла переменной $fd.
В >(manager $i)запусках manager $iи в основном заменители >(manager $i)с путем к STDIN этого процесса. Так что, если он managerбыл запущен как PID 1234, >(manager $i)может быть заменен на /proc/1234/fd/0(это зависит от ОС).
Таким образом, предполагая, что следующий доступный номер дескриптора файла равен 10, и менеджер запускается с PID 1234, команда в exec {fd}> >(manager $i)основном становится exec 10>/proc/1234/fd/0, и bash теперь имеет файловый дескриптор, указывающий на STDIN этого менеджера.
Затем, поскольку bash вставляет этот номер дескриптора файла $fd, мы добавляем этот дескриптор в массив fdsдля дальнейшего использования.
В остальном все довольно просто. Мастер читает строку из STDIN, перебирает все файловые дескрипторы $fdsи отправляет строку в этот дескриптор файла ( printf ... >&$fd).
Результат выглядит так:
$ /tmp/test.sh
hello
master: hello
manager[0:8876]: hello
manager[1:8877]: hello
manager[4:8880]: hello
manager[2:8878]: hello
manager[3:8879]: hello
world
master: world
manager[0:8876]: world
manager[1:8877]: world
manager[3:8879]: world
manager[2:8878]: world
manager[4:8880]: world
Где я напечатал helloи world.