जो आप पूरा करने की कोशिश कर रहे हैं, उसके लिए शब्द बहुसंकेतन है ।
यह बैश में काफी आसानी से पूरा किया जा सकता है, लेकिन इसके लिए कुछ अधिक उन्नत बैश सुविधाओं की आवश्यकता होती है।
मैंने आपके आधार पर एक स्क्रिप्ट बनाई, जो मुझे लगता है कि वही करता है जो आप पूरा करने की कोशिश कर रहे हैं। मैं इसे नीचे समझाता हूँ।
#!/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
इसके बजाय का उपयोग करते हैं $$
जैसे $$
उपधाराओं के लिए अद्यतन नहीं किया जाता है (जिसे हम लॉन्च करने के लिए उपयोग करेंगे manager
।
fds
एक ऐसा सरणी है जो फ़ाइल डिस्क्रिप्टर को विभिन्न manager
s स्पॉन्ड के STDIN पाइपों की ओर इंगित करता है।
फिर हम 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
, और 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
।