2009-11-27 21 views
32

मेरे पास Broken pipe (Errno::EPIPE) त्रुटि पॉप अप है और मुझे समझ में नहीं आता कि यह क्या है या इसे कैसे ठीक किया जाए। पूर्ण त्रुटि है: मेरे कोड काटूटा हुआ पाइप (एरर्नो :: ईपीआईपीई)

example.rb:19:in `write': Broken pipe (Errno::EPIPE) 
    from example.rb:19:in `print' 
    from example.rb:19 

लाइन 19 है:

vari.print("x=" + my_val + "&y=1&z=Add+Num\r\n") 

उत्तर

21

इसका मतलब है कि जो कुछ भी कनेक्शन प्रिंट नहीं रह गया है जुड़ा हुआ है के लिए outputting है। मुमकिन है कार्यक्रम कुछ अन्य कार्यक्रम के लिए इनपुट के रूप में शुरू किया:

% ruby_program | another_program 

क्या हुआ है कि another_program प्रश्न में print से पहले कुछ समय से बाहर निकल गया है।

+0

असल में, यह कोड सभी http अनुरोध के लिए है। क्या इसका मतलब यह है कि उस बिंदु पर सर्वर कनेक्ट नहीं है? ऐसा लगता है कि यह यादृच्छिक रूप से हो रहा है। – sepiroth

+0

मुझे रूबी के बारे में बहुत कुछ पता नहीं है, लेकिन ईपीआईपीई शायद नेटवर्क डिस्कनेक्शन हो सकता है। लिनक्स पर मैं उम्मीद करता हूं कि त्रुटि उस स्थिति के लिए ENETRESET, ECONNABORTED, ECONNRESET, ENOTCONN, या ESHUTDOWN होगी। – wallyk

+1

@ प्रेरणा: 'EPIPE' _system_- परिभाषित है; यह एक सिस्टम कॉल द्वारा रिपोर्ट किया गया निकास कोड है जो 'सिगिपी' सिग्नल को ट्रिगर करता है, जो आम तौर पर इंगित करता है कि _pipe_ के _reading_ अंत में प्रक्रिया समाप्त हो गई है (जबकि _writing_ end अभी भी पाइप पर लिखने की कोशिश कर रहा है); इसके अतिरिक्त, _network_ संदर्भ में, [यह] (https://www.gnu.org/software/libc/manual/html_mono/libc.html#Operation- त्रुटि- सिग्नल) कहता है: "सिगिपी 'का एक अन्य कारण है जब आप एक _socket_ पर आउटपुट करने का प्रयास करते हैं जो कनेक्ट नहीं है। [डेटा भेजना] देखें (https://www.gnu.org/software/libc/manual/html_mono/libc.html#Sending-Data) "। – mklement0

12

@wallyk समस्या पर सही है। एक समाधान Signal.trap साथ संकेत कब्जा करने के लिए है:

Signal.trap("PIPE", "EXIT") 
9

हालांकि संकेत जाल काम करते हैं, के रूप में tokland ने कहा, वे आवेदन विस्तृत परिभाषित कर रहे हैं और कुछ अनपेक्षित व्यवहार का कारण आप किसी अन्य तरीके से एक टूटी हुई पाइप को संभालने के लिए चाहते हैं, तो कर सकते हैं आपके ऐप में कहीं और।

मैं मानक मानक का उपयोग करके सुझाव देता हूं क्योंकि त्रुटि अभी भी मानक त्रुटि से प्राप्त होती है। त्रुटियों के इस मॉड्यूल के बारे में अधिक: http://ruby-doc.org/core-2.0.0/Errno.html

उदाहरण:

begin 
    vari.print("x=" + my_val + "&y=1&z=Add+Num\r\n") 
rescue Errno::EPIPE 
    puts "Connection broke!" 
end 

संपादित करें: यह ध्यान देना महत्वपूर्ण है (जैसा कि @ mklement0 टिप्पणी में करता है) है कि आप मूल रूप से अपने उत्पादन कुछ करने के लिए कहते हैं का उपयोग कर पाइप कर रहे थे एसटीडीओयूटी पर आउटपुट की उम्मीद है, उपर्युक्त कोड में अंतिम डालर एक और एरर्नो :: ईपीआईपीई अपवाद उठाएंगे। वैसे भी STDERR.puts का उपयोग करना शायद बेहतर अभ्यास है।

begin 
    vari.print("x=" + my_val + "&y=1&z=Add+Num\r\n") 
rescue Errno::EPIPE 
    STDERR.puts "Connection broke!" 
end 
+0

+1 समझदार सलाह देखें – tokland

+1

समझदार लगता है, लेकिन व्यवहार में (रूबी 2.0.0) मैं इस त्रुटि को पकड़ने में असमर्थ रहा हूं; 'रूबी-ए' शुरू करने का प्रयास करें; रखता है (1..10000)। एमएपी {| एन | "रेखा # {एन}"}; बचाव Errno :: EPIPE; डालता है "नहीं कर सकता: # {$! संदेश}"; अंत '| सिर '- यह अभी भी टूटता है; यहां तक ​​कि 'अपवाद' को बचाने की कोशिश भी काम नहीं करता है। क्या मुझे कुछ याद आ रही है? – mklement0

+2

@ mklement0 आप वास्तव में अपवाद को बचा रहे हैं, लेकिन अपवाद आपके बचाव कथन के भीतर फिर से उठाया जाता है क्योंकि आप अपनी कस्टम अपवाद स्ट्रिंग को STDOUT पर लिखने की कोशिश कर रहे हैं जिसे अभी भी सिर पर पाइप किया जा रहा है (और जिसका पाइप टू हेड टूटा गया है) । यदि आप इसे 'रूबी-ए' शुरू करते हैं; रखता है (1..10000)। एमएपी {| एन | "रेखा # {एन}"}; बचाव Errno :: EPIPE; STDERR.puts "नहीं कर सकता: # {$! संदेश}"; अंत '| सिर 'आप देखेंगे कि यह वास्तव में मूल Errno :: EPIPE अपवाद को बचाता है। –

6

निम्नलिखित मुख्य रूप से CLIs के रूप में कार्य करने के लिए डिज़ाइन रूबी लिपियों के लिए लागू होता है; SIGPIPE प्राप्त करते समय आमतौर पर सीएलआई को को एक विशिष्ट निकास कोड के साथ चुपचाप समाप्त करने की आवश्यकता होती है; उन स्क्रिप्ट्स के लिए जिन्हें SIGPIPE के केस-बाय-केस हैंडलिंग की आवश्यकता होती है, donovan.lampa's helpful answer पर विचार करें।

की मदद के लिए wallyk's helpful answer और tokland's helpful answer:

यदि आप चाहते हैं प्रदर्शनी सिस्टम के डिफ़ॉल्ट व्यवहार को अपनी स्क्रिप्ट, अधिकांश यूनिक्स उपयोगिताओं (जैसे, cat) करते हैं, का उपयोग

Signal.trap("SIGPIPE", "SYSTEM_DEFAULT") 
के रूप में आपकी स्क्रिप्ट की शुरुआत में

अब, जब अपनी स्क्रिप्ट SIGPIPE संकेत प्राप्त (यूनिक्स सिस्टम पर), सिस्टम के डिफ़ॉल्ट व्यवहार होगा:

  • चुपचाप समाप्त अपनी स्क्रिप्ट
  • रिपोर्ट बाहर निकलें कोड 141 (जो 128 के रूप में गणना की जाती है (सिग्नल द्वारा समाप्ति का संकेत) + 13 (SIGPIPE की संख्या))

इसके विपरीत, Signal.trap("PIPE", "EXIT") निकास कोड 0 की रिपोर्ट करेगा।

ध्यान दें कि एक खोल संदर्भ में बाहर निकलने के कोड बार नहीं एक कमांड जैसे ruby examble.rb | head में स्पष्ट, कारण है कि शेल (डिफ़ॉल्ट रूप से) केवल पिछले आदेश के बाहर निकलने के कोड की रिपोर्ट।

bash में, आप पाइप लाइन में सभी आदेशों के निकास कोड को देखने के लिए ${PIPESTATUS[@]} जांच कर सकते हैं।

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