एक नामित पाइप से स्टड प्राप्त करना


10

मैं जो करने की कोशिश कर रहा हूं वह एक टर्मिनल विंडो में अजगर को चलाता है और एक नामित पाइप से इसे रीडायरेक्ट करता है। फिर मैं दूसरे टर्मिनल में नामित पाइप को लिखता हूं और उस आदेश को अजगर पर निष्पादित करता हूं।

टर्मिनल 1:

mkfifo p1
python < p1

टर्मिनल 2:

echo -n "print \"Hello World\"" > p1

क्या होता है - अजगर प्रिंट Hello Worldऔर बाहर निकलता है। मैं जो करना चाहता हूं वह अगले आदेश लेने के लिए अजगर को चालू रखना है। मैं इसे शेल में कैसे करूं?

जवाबों:


10

आपको

  • अजगर को अंतःक्रियात्मक रूप से चलाएं, भले ही इसकी स्टडिन एक टर्मिनल: उपयोग न हो python -i
  • पाइप का लेखन अंत खुला रखें, अन्यथा अजगर ईओएफ का पता लगाएगा और बाहर निकल जाएगा।

इसलिए:

python -i < p1

और कहीं और:

exec 3> p1
echo '1j*1j' >&3
...
# and when done, close that file descriptor so python sees the EOF:
exec 3>&-

धन्यवाद! इसने काम कर दिया। आपने जो किया है, उससे मैं परिचित नहीं हूं। क्या आप यह बताने के लिए कृपया अपने उत्तर में कुछ विवरण जोड़ेंगे कि क्या हो रहा है। क्या है exec 3> p1कर रहे हैं और क्या है &3और exec 3> &1? धन्यवाद।
भगवान लोह।

1
आपके उत्तर ने मुझे इस बैनर की याद दिला दी - sphotos-b.xx.fbcdn.net/hphotos-ash4/… यह फेसबुक पर एक मित्र का कवर चित्र है :-)
लॉर्ड लोह।

एक सवाल, क्या यहाँ भी ऐसा exec 3>&-ही होगा exec 3>&1?
वाइल्डकार्ड

1
@Wildcard मुझे संदेह है कि मैं 3>&-यहाँ लिखना चाहता हूँ । 3>&1के रूप में अच्छी तरह से काम करेगा, लेकिन थोड़ा समझ में आता है। धन्यवाद
स्टीफन Chazelas

5

आप इसे लिखने के tail -fबाद पंद्रो को खुला रखने के लिए उपयोग कर सकते echoहैं।

tail -n1 -f p1 | python

यह क्यों काम करता है

pythonसे पढ़ रहा है p1। जब यह फ़ाइल के अंत तक पहुँच जाता है, तो यह पढ़ना बंद कर देता है। यह फ़ाइल रीड के लिए सामान्य व्यवहार है, भले ही फ़ाइल एक नामित पाइप हो। (पालन) ध्वज के tailसाथ -fएक फ़ाइल इसके अंत तक पहुंचने के बाद पढ़ती रहेगी।


मैंने echo "print \"Hello World\" " > p1दूसरे टर्मिनल में कोशिश की और कुछ नहीं हुआ - लेकिन टर्मिनल भी अवरुद्ध नहीं था। अजगर के साथ टर्मिनल तब तक अवरुद्ध रहा जब तक कि मैं ^cइसे बाहर नहीं निकाल पाया और अजगर द्वारा प्रदर्शित कीबोर्ड इंटरप्ट मैसेज के साथ अजगर को समाप्त कर दिया।
भगवान लोह।

मैंने इस tail -fट्रिक का उपयोग तब किया जब एक नामित पाइप के माध्यम से ब्लॉक-स्प्लिट टार आर्काइव को खोल दिया। यह अद्भुत काम किया।
मैल

2

आपको एक बार में पूरा कार्यक्रम भेजने की आवश्यकता है।

जब आप कॉल रन python < p1करते हैं तो शेल अजगर के आह्वान से पहले इनपुट का इंतजार कर रहा है। यानी, जब तक पूरे डेटा स्ट्रीम को शेल द्वारा पढ़ा नहीं जाता है, तब तक अजगर पूरी तरह से निष्पादित करना शुरू नहीं करता है और फिर इसे पूरी तरह से पारित कर दिया जाता है python

यहां तक ​​कि python -u p1इसके बजाय (जो कि फ़ाइल से अनफ़रफ़र्ड और रीड होता है p1) चल रहा है, pythonइससे पहले कि वह किसी भी फ़ाइल को निष्पादित करने से पहले पूरी फ़ाइल को पढ़ने की कोशिश करेगा।

इस प्रयोग को आजमाएं।

टर्मिनल 1:

mkfifo p1
python < p1

टर्मिनल 2:

cat > p1
print "Hello World"
print "Hello World"

आप देखेंगे कि आप कई पंक्तियों को भेज सकते हैं लेकिन शब्द 1 में अजगर कुछ नहीं करता है। अब ctrl+ दबाएं D। पूरा कार्यक्रम एक ही बार में निष्पादित होता है।

इसलिए, संक्षेप में, यदि आप एक पाइप से पढ़ना चाहते हैं, तो आपको पूरे कार्यक्रम को भेजने की आवश्यकता है। आप इस तरह से अंतःक्रियात्मक रूप से अजगर का उपयोग नहीं कर सकते।


1

हो सकता है कि पूंछ का दृष्टिकोण बेहतर (अधिक लचीला) हो लेकिन विकल्प के रूप में:

{ echo -n "print \"Hello World\""; cat; } > p1

यह काम नहीं करता जैसा मैं चाहता हूं। -nओ हटाया जा सकता है। और उसके बाद, 0. echoकमांड वाला टर्मिनल ब्लॉक हो जाता है। 1. अजगर तब तक कमांड को निष्पादित नहीं करता है जब तक कि मैं टर्मिनल ^cमें प्रेस नहीं करता echoऔर दोनों प्रक्रिया समाप्त हो जाती है।
भगवान लोह।

1
@LordLoh। एक बफरिंग समस्या हो सकती है। संभवत: अजगर कमांड को निष्पादित करेगा यदि पर्याप्त आउटपुट बनाया गया है ताकि पहली पंक्ति अंततः फीफो को लिखी जाए। लेकिन जैसा कि एक कार्य समाधान है इस समस्या को हल करने में प्रयास करने का कोई मतलब नहीं होगा।
हौके लागिंग
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.