คำศัพท์ที่คุณต้องการทำให้สำเร็จคือการทำมัลติเพล็กซ์
สิ่งนี้สามารถทำได้ค่อนข้างง่ายในการทุบตี แต่มันต้องมีคุณสมบัติทุบตีขั้นสูง
ฉันสร้างสคริปต์ตามที่คุณคิดว่าทำในสิ่งที่คุณพยายามจะทำ ฉันจะอธิบายด้านล่าง
#!/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 เราใช้$BASHPID
แทน$$
เป็น$$
ไม่ได้รับการปรับปรุงสำหรับ subshells manager
(ซึ่งเป็นสิ่งที่เราจะใช้ในการเปิดตัว
fds
คืออาร์เรย์ที่จะเก็บไฟล์ descriptors ที่ชี้ไปยังท่อ STDIN ของmanager
s ต่างๆที่เกิดขึ้น
จากนั้นเราวนซ้ำและสร้าง 5 กระบวนการผู้จัดการ ฉันใช้for (( ))
ไวยากรณ์แทนวิธีที่คุณทำเพราะสะอาดกว่า นี่คือการทุบตีที่เฉพาะเจาะจง แต่หลายสิ่งที่สคริปต์นี้ไม่เฉพาะทุบตีดังนั้นจึงอาจไปตลอดทาง
exec {fd}> >(manager $i)
ต่อไปเราจะได้รับการ สิ่งนี้จะทำสิ่งที่เฉพาะเจาะจงมากขึ้นทุบตี ครั้งแรกของซึ่งเป็น
{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
จริงและตอนนี้ทุบตีจะมีตัวอธิบายไฟล์ชี้ไปที่ STDIN ของตัวจัดการนั้น
จากนั้นเมื่อทุบตีใส่หมายเลขตัวอธิบายไฟล์$fd
นั้นเราจึงเพิ่มตัวอธิบายนั้นลงในอาร์เรย์fds
เพื่อใช้ในภายหลัง
ที่เหลือก็ค่อนข้างเรียบง่าย ต้นแบบอ่านบรรทัดจาก STDIN ซ้ำทุกตัวอธิบายไฟล์ใน$fds
และส่งบรรทัดไปยังไฟล์ desciptor ( 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