आप जानते हैं, मुझे यकीन नहीं है कि आपके डायग्राम के चित्रण के रूप में आपको दोहराए जाने वाले फीडबैक लूप की आवश्यकता है, क्योंकि हो सकता है कि आप कॉपोरोसेस के बीच एक सतत पाइपलाइन का उपयोग कर सकें । फिर से, यह हो सकता है कि इसमें बहुत अधिक अंतर न हो - एक बार एक कोप्रोसेस पर एक लाइन खोलने के बाद आप सामान्य शैली के लूप को लागू कर सकते हैं और साधारण से बहुत कुछ किए बिना जानकारी को लिखना और उससे जानकारी पढ़ना।
पहली जगह में, यह प्रतीत होता है कि bc
आप के लिए एक कॉपीराइट के लिए एक प्रमुख उम्मीदवार है। में bc
आप कर सकते हैं define
कार्यों कि आपके स्यूडोकोड में के लिए काफी है कि तुम क्या पूछना कर सकते हैं। उदाहरण के लिए, ऐसा करने के लिए कुछ बहुत ही सरल कार्य इस तरह दिख सकते हैं:
printf '%s()\n' b c a |
3<&0 <&- bc -l <<\IN <&3
a=1; b=0; c=0;
define a(){ "a="; return (a = c+1); }
define b(){ "b="; return (b = 3*a); }
define c(){ "c="; return (c = s(b)); }
IN
... जो छपेगा ...
b=3
c=.14112000805986722210
a=1.14112000805986722210
लेकिन निश्चित रूप से, यह पिछले नहीं है । जैसे ही printf
पाइप के क्विट्स (printf
a()\n
पाइप के बाद राइट्स ) के सबस्क्रिप्शन को पाइप फटा जाता है और bc
इनपुट बंद हो जाता है और वह भी क्विट हो जाता है। यह लगभग उतना उपयोगी नहीं है जितना यह हो सकता है।
@derobert ने पहले ही FIFO का उल्लेख किया है क्योंकि उपयोगिता के साथ एक नामित पाइप फ़ाइल बनाकर किया जा सकता है mkfifo
। ये अनिवार्य रूप से सिर्फ पाइप के रूप में अच्छी तरह से हैं, सिवाय सिस्टम कर्नेल के दोनों छोरों पर एक फाइलसिस्टम प्रविष्टि को जोड़ता है। ये बहुत उपयोगी हैं, लेकिन यह अच्छा होगा यदि आप बिना किसी पाइप को जोखिम में डाले इसे फाइलसिस्टम में स्नूप कर सकते हैं।
जैसा कि होता है, आपका खोल यह बहुत कुछ करता है। यदि आप एक शेल का उपयोग करते हैं जो प्रतिस्थापन की प्रक्रिया को कार्यान्वित करता है तो आपके पास एक स्थायी पाइप प्राप्त करने का एक बहुत ही सरल साधन है - इस तरह का कि आप एक पृष्ठभूमि प्रक्रिया को असाइन कर सकते हैं जिसके साथ आप संवाद कर सकते हैं।
में bash
, उदाहरण के लिए, आप कैसे प्रक्रिया प्रतिस्थापन काम करता है देख सकते हैं:
bash -cx ': <(:)'
+ : /dev/fd/63
आप देखते हैं कि यह वास्तव में एक प्रतिस्थापन है । खोल विस्तार के दौरान एक मूल्य को प्रतिस्थापित करता है जो एक पाइप के लिंक के मार्ग से मेल खाता है । आप इसका लाभ उठा सकते हैं - आपको उस पाइप का उपयोग करने के लिए विवश होने की जरूरत नहीं है, जो कि प्रतिस्थापन के भीतर जो भी प्रक्रिया चलती है, उसके साथ संवाद करने के लिए ...()
bash -c '
eval "exec 3<>"<(:) "4<>"<(:)
cat <&4 >&3 &
echo hey cat >&4
read hiback <&3
echo "$hiback" here'
... जो प्रिंट करता है ...
hey cat here
अब मुझे पता है कि अलग-अलग गोले अलग-अलग तरीकों से मैथुन करते हैं - और यह कि एक bash
को स्थापित करने के लिए एक विशिष्ट वाक्यविन्यास है (और शायद एक के लिए zsh
भी) - लेकिन मुझे नहीं पता कि वे चीजें कैसे काम करती हैं। मुझे सिर्फ इतना पता है कि आप उपरोक्त वाक्यविन्यास का उपयोग वस्तुतः दोनों में बिना किसी कठोरता के कर सकते हैं bash
और zsh
- और आप यहाँ पर एक ही तरह का काम कर सकते हैं dash
और busybox ash
यहाँ एक ही उद्देश्य प्राप्त कर सकते हैं -दस्तावेज (क्योंकि dash
और busybox
यहाँ- अन्य दो के रूप में अस्थायी फ़ाइलों के बजाय पाइप के साथ दस्तावेज़) ।
तो, जब लागू bc
...
eval "exec 3<>"<(:) "4<>"<(:)
bc -l <<\INIT <&4 >&3 &
a=1; b=0; c=0;
define a(){ "a="; return (a = c+1); }
define b(){ "b="; return (b = 3*a); }
define c(){ "c="; return (c = s(b)); }
INIT
export BCOUT=3 BCIN=4 BCPID="$!"
... यह कठिन हिस्सा है। और यह मजेदार हिस्सा है ...
set --
until [ "$#" -eq 10 ]
do printf '%s()\n' b c a >&"$BCIN"
set "$@" "$(head -n 3 <&"$BCOUT")"
done; printf %s\\n "$@"
... जो प्रिंट करता है ...
b=3
c=.14112000805986722210
a=1.14112000805986722210
#...24 more lines...
b=3.92307618030433853649
c=-.70433330413228041035
a=.29566669586771958965
... और यह अभी भी चल रहा है ...
echo a >&"$BCIN"
read a <&"$BCOUT"
echo "$a"
... जो सिर्फ मेरे लिए अंतिम मान हो जाता bc
है a
बल्कि बुला से a()
यह और प्रिंट बढ़ाने के लिए समारोह ...
.29566669586771958965
यह तब तक चलता रहेगा, जब तक कि मैं इसे मार न दूं और इसके आईपीसी पाइप को फाड़ दूं ...
kill "$BCPID"; exec 3>&- 4>&-
unset BCPID BCIN BCOUT