2011-05-10 13 views
15

इस परिदृश्य पर विचार करें:फीफो रोकें बंद कर दिया फीफो

एक फीफो नामित test बनाई गई है। एक टर्मिनल विंडो में (ए) मैं cat <test चलाता हूं और दूसरे में (बी) cat >test चलाता हूं। अब विंडो बी में लिखना और विंडो ए में आउटपुट प्राप्त करना संभव है। प्रक्रिया ए को समाप्त करना और इसे फिर से लॉन्च करना भी संभव है और फिर भी इस सेटअप को संदिग्ध के रूप में उपयोग करने में सक्षम हो सकता है। हालांकि यदि आप विंडो बी में प्रक्रिया को समाप्त करते हैं, बी (जहां तक ​​मुझे पता है) एफआईएफओ के माध्यम से ए को संसाधित करने के लिए एक ईओएफ भेजता है और उसे भी समाप्त कर देता है।

वास्तव में, यदि आप ऐसी प्रक्रिया चलाते हैं जो ईओएफ पर समाप्त नहीं होता है, तो भी आप प्रक्रिया में रीडायरेक्ट किए गए अपने फीफो का उपयोग करने में सक्षम नहीं होंगे। जो मुझे लगता है क्योंकि यह फीफो बंद माना जाता है।

क्या इस समस्या के आसपास काम करने के लिए वैसे भी है?

इस समस्या में भाग लेने का कारण यह है क्योंकि मैं स्क्रीन सत्र में चल रहे अपने Minecraft सर्वर पर आदेश भेजना चाहता हूं। उदाहरण के लिए: echo "command" >FIFO_to_server। स्क्रीन द्वारा स्वयं का उपयोग करके यह संभवतः संभव है लेकिन मैं स्क्रीन के साथ बहुत सहज नहीं हूं, मुझे लगता है कि केवल पाइप का उपयोग करने वाला समाधान एक सरल और क्लीनर होगा।

उत्तर

26

ए फ़ाइल से पढ़ रहा है। जब यह फ़ाइल के अंत तक पहुंच जाता है, तो यह पढ़ना बंद कर देता है। यह सामान्य व्यवहार है, भले ही फ़ाइल एक फीफो हो। अब आपके पास चार दृष्टिकोण हैं।

  1. पाठक के कोड को फ़ाइल के अंत के बाद इसे पढ़ने के लिए बदलें। यह कह रहा है कि इनपुट फ़ाइल अनंत है, और फ़ाइल के अंत तक पहुंचने सिर्फ एक भ्रम है। आपके लिए व्यावहारिक नहीं है, क्योंकि आपको Minecraft सर्वर कोड बदलना होगा।
  2. यूनिक्स दर्शन लागू करें। आपके पास एक लेखक और एक पाठक है जो प्रोटोकॉल पर सहमत नहीं है, इसलिए आप उन्हें जोड़ने वाले टूल को इंटरैक्ट करते हैं। ऐसा होने पर, यूनिक्स टूलबॉक्स में ऐसा टूल है: tail -f। फ़ाइल के अंत को देखने के बाद भी tail -f अपनी इनपुट फ़ाइल से पढ़ता रहता है। अपने सभी ग्राहकों पाइप से बात करें, और Minecraft सर्वर से कनेक्ट tail -f:

    tail -n +1 -f client_pipe | minecraft_server & 
    
  3. As mentioned by jilles, एक चाल का उपयोग करें: पाइप कई लेखकों का समर्थन है, और केवल बंद हो जाते हैं जब पिछले लेखक चली जाती है। तो सुनिश्चित करें कि एक ऐसा ग्राहक है जो कभी नहीं चलेगा।

    while true; do sleep 999999999; done >client_pipe & 
    
  4. समस्या यह है कि सर्वर मौलिक एक भी ग्राहक को संभालने के लिए बनाया गया है। एकाधिक ग्राहकों को संभालने के लिए, आपको सॉकेट का उपयोग करने के लिए बदलना चाहिए। सॉकेट को "मेटा-पाइप" के रूप में सोचें: सॉकेट से कनेक्ट करने से एक पाइप बन जाती है, और क्लाइंट डिस्कनेक्ट होने के बाद, वह विशेष पाइप बंद हो जाती है, लेकिन सर्वर अधिक कनेक्शन स्वीकार कर सकता है। यह स्वच्छ दृष्टिकोण है, क्योंकि यह भी सुनिश्चित करता है कि यदि आप दो क्लाइंट एक ही समय में कनेक्ट होने के लिए होते हैं तो आप डेटा को मिश्रित नहीं करेंगे (पाइप का उपयोग करके, उनके आदेशों को अलग किया जा सकता है)। हालांकि, इसे Minecraft सर्वर को बदलने की आवश्यकता है।

+0

दुर्भाग्यवश 'पूंछ' ईओएफ के लिए इंतजार कर रहा है, इसलिए यह लाइन द्वारा पाइप लाइन से सामग्री को पास नहीं करेगा। – pabouk

+2

@pabouk इस बग को इंगित करने के लिए धन्यवाद: 'tail -n 1 -f' इनपुट को छोड़ देगा जो इसे शुरू करने से पहले उपलब्ध था या इसे पढ़ने से तेज़ी से उपलब्ध कराया गया था।मेरा मतलब था 'tail -n +1 -f', जो सीधे आउटपुट करना शुरू करता है। – Gilles

+2

धन्यवाद। मैंने पहले यह कोशिश की है लेकिन '-n + 1' ने काम नहीं किया जैसा कि मैंने उम्मीद की थी। अब जब आपने पुष्टि की है कि यह सही तरीका है कि मैंने समस्या की जांच की और महसूस किया कि समस्या 'पूंछ' के stdout के ब्लॉक बफरिंग (डिफ़ॉल्ट लाइन बफरिंग के बजाय) में है। लाइन पाइपिंग द्वारा लाइन के लिए समाधान: 'stdbuf -oL tail -n +1 -f client_pipe | कमांड ' – pabouk

6

ऐसी प्रक्रिया शुरू करें जो लिफा लिखने के लिए खुली रहती है और अनिश्चित काल तक चलती रहती है। यह पाठकों को अंत-ऑफ-फाइल स्थिति देखने से रोक देगा।

संबंधित मुद्दे