달성하려는 용어는 멀티플렉싱 입니다.
이것은 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
STDIN에서 간단히 읽고 식별자와 줄을 STDOUT에 쓰는 bash 함수입니다. 우리는 서브 쉘을 위해 업데이트되지 않는 as $BASHPID
대신에 사용한다 (이것은 우리가 발사하는데 사용할 것이다) .$$
$$
manager
fds
manager
스폰 된 다양한 파일의 STDIN 파이프를 가리키는 파일 디스크립터를 보유하는 배열입니다 .
그런 다음 5 개의 관리자 프로세스를 반복 작성합니다. for (( ))
더 깔끔한 방식으로 구문을 사용합니다 . 이것은 bash에만 해당되지만이 스크립트가 수행하는 몇 가지 작업은 bash마다 다르므로 계속 진행될 수 있습니다.
다음에 우리는 exec {fd}> >(manager $i)
. 이것은 몇 가지 bash 특정 작업을 수행합니다.
첫 번째는입니다 {fd}>
. 그러면 번호 10 또는 그 이후에 사용 가능한 다음 파일 디스크립터를 가져 와서 해당 파일 디스크립터에 지정된 파이프의 쓰기 측이있는 파이프를 열고 파일 디스크립터 번호를 변수에 지정합니다 $fd
.
>(manager $i)
출시 manager $i
기본적으로 대체 >(manager $i)
그 과정의 STDIN에 대한 경로. 따라서 manager
PID 1234로 시작된 경우 (OS에 따라 다름) >(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
.