Yapmaya çalıştığınız şeyin terimi çoğullamadır .
Bu, bash'de oldukça kolay bir şekilde gerçekleştirilebilir, ancak daha gelişmiş bash özellikleri gerektirir.
Senin yapmaya çalıştığın şeyi yaptığını düşünüyorum senin dayalı bir senaryo oluşturdum. Aşağıda açıklayacağım.
#!/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'den basitçe okuyan ve tanımlayıcısını ve satırını STDOUT'a yazan bir bash işlevidir. Alt kabuklar için güncellenmemiş olarak kullanmak $BASHPID
yerine ( başlatmak için kullanacağımız şey budur .$$
$$
manager
fds
, manager
ortaya çıkan çeşitli s'nin STDIN borularına işaret eden dosya tanımlayıcılarını tutacak bir dizidir .
Daha sonra 5 yönetici süreci oluşturup oluşturuyoruz. for (( ))
Sözdizimini daha temiz olduğu gibi yapmak yerine kullanıyorum . Bu bash'a özgüdür, ancak bu betiğin yaptığı birkaç şey bash'a özgüdür, bu yüzden sonuna kadar gidebilir.
Sonra gidiyoruz exec {fd}> >(manager $i)
. Bu, bash'a özgü birkaç şey daha yapar.
Bunlardan ilki {fd}>
. Bu, bir sonraki kullanılabilir dosya tanımlayıcısını 10 sayısı üzerinde veya sonrasında alır, borunun yazma tarafı o dosya tanımlayıcısına atanmış bir boru açar ve dosya tanımlayıcı numarasını değişkene atar $fd
.
Bu işlemin bir STDIN yolunu >(manager $i)
başlatır manager $i
ve temel olarak >(manager $i)
onun yerine geçer . Bu nedenle manager
, PID 1234 olarak başlatıldıysa, bunun >(manager $i)
yerine ikame edilebilir /proc/1234/fd/0
(bu işletim sistemine bağlıdır).
Dolayısıyla, bir sonraki kullanılabilir dosya tanımlayıcı numarasının 10 olduğunu ve PID 1234 ile yönetici başlatıldığını varsayarsak, komut exec {fd}> >(manager $i)
temelde olur exec 10>/proc/1234/fd/0
ve bash şimdi bu yöneticinin STDIN'ini gösteren dosya tanımlayıcıya sahiptir.
Sonra bash bu dosya tanımlayıcı numarasını koyduğundan, $fd
bu tanımlayıcıyı fds
daha sonra kullanmak üzere diziye ekleriz .
Geri kalanı oldukça basit. Master, STDIN'den bir satır okur, içindeki tüm dosya tanımlayıcılarını $fds
tekrarlar ve satırı o dosya tanımlayıcısına ( printf ... >&$fd
) gönderir .
Sonuç şuna benzer:
$ /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
Nereye yazdım hello
ve world
.