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
managerSTDIN'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 $BASHPIDyerine ( başlatmak için kullanacağımız şey budur .$$$$manager
fds, managerortaya çı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 $ive 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/0ve 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, $fdbu tanımlayıcıyı fdsdaha 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ı $fdstekrarlar 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 hellove world.