Istilah untuk apa yang ingin Anda capai adalah multiplexing .
Ini dapat dilakukan dengan cukup mudah di bash, tetapi membutuhkan beberapa fitur bash yang lebih canggih.
Saya membuat skrip berdasarkan pada Anda yang menurut saya melakukan apa yang ingin Anda capai. Saya akan jelaskan di bawah ini.
#!/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
adalah fungsi bash yang hanya membaca dari STDIN dan menulis pengenalnya dan baris ke STDOUT. Kami menggunakan $BASHPID
alih-alih $$
karena $$
tidak mendapatkan pembaruan untuk subkulit (yang akan kami gunakan untuk memulai manager
.
fds
adalah sebuah array yang akan menahan deskriptor file yang menunjuk ke pipa STDIN dari berbagai manager
s yang dimunculkan.
Lalu kami mengulang dan membuat 5 proses manajer. Saya menggunakan for (( ))
sintaks daripada cara Anda melakukannya karena lebih bersih. Ini khusus untuk bash, tetapi beberapa hal yang dilakukan skrip ini adalah khusus untuk bash, jadi sebaiknya lakukan semuanya.
Selanjutnya kita sampai exec {fd}> >(manager $i)
. Ini melakukan beberapa hal spesifik bash lebih.
Yang pertama adalah {fd}>
. Ini mengambil deskriptor file yang tersedia berikutnya pada atau setelah nomor 10, membuka pipa dengan sisi penulisan pipa yang ditugaskan untuk deskriptor file tersebut, dan memberikan nomor deskriptor file ke variabel $fd
.
The >(manager $i)
peluncuran manager $i
dan pada dasarnya pengganti >(manager $i)
dengan jalan ke STDIN dari proses itu. Jadi jika manager
diluncurkan sebagai PID 1234, >(manager $i)
bisa diganti dengan /proc/1234/fd/0
(ini tergantung OS).
Jadi dengan asumsi nomor deskriptor file yang tersedia berikutnya adalah 10, dan manajer diluncurkan dengan PID 1234, perintah exec {fd}> >(manager $i)
pada dasarnya menjadi exec 10>/proc/1234/fd/0
, dan bash sekarang memiliki deskriptor file yang menunjuk ke STDIN dari manajer itu.
Kemudian karena bash memasukkan nomor deskriptor file ke dalam $fd
, kami menambahkan deskriptor itu ke array fds
untuk digunakan nanti.
Sisanya cukup sederhana. Master membaca baris dari STDIN, mengulangi semua deskriptor file di $fds
, dan mengirimkan baris ke file desciptor ( printf ... >&$fd
).
Hasilnya terlihat seperti ini:
$ /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
Di mana saya mengetik hello
dan world
.
echo -- "$line"
atauprintf "%s\n" "$line"
- tetapi mengapa Anda perlu menggunakan--
ketika argumen berikutnya adalah hard-coded (dan tidak dimulai dengan-
)?tee
danbash
:Jika jumlah manajer dapat dikonfigurasi atau jika Anda ingin output dari manajer yang berbeda tidak tercampur:
sumber