2012-05-02 19 views
18

मुझे कुछ कोड विरासत में मिला है जो मुद्रित करने के लिए कॉल के दौरान उठाए गए इनपुट/आउटपुट त्रुटि के कारण समय-समय पर (यादृच्छिक रूप से) विफल हो रहा है। मैं उठाए जा रहे अपवाद का कारण निर्धारित करने की कोशिश कर रहा हूं (या कम से कम, इसे बेहतर समझें) और इसे सही तरीके से कैसे संभालें।IOError इनपुट/आउटपुट त्रुटि जब मुद्रण

जब (एक 2.6.6 दुभाषिया में, CentOS 5.5 पर चलने वाले) अजगर की निम्न पंक्ति को क्रियान्वित:

print >> sys.stderr, 'Unable to do something: %s' % command 

अपवाद उठाया है (ट्रैस बैक छोड़े गए):

IOError: [Errno 5] Input/output error 

संदर्भ के लिए , यह आम तौर पर उस समय बड़ा कार्य करने का प्रयास कर रहा है:

from subprocess import Popen, PIPE 
import sys 
def run_commands(commands): 
    for command in commands: 
     try: 
      out, err = Popen(command, shell=True, stdout=PIPE, stderr=PIPE).communicate() 
      print >> sys.stdout, out 
      if err: 
       raise Exception('ERROR -- an error occurred when executing this command: %s --- err: %s' % (command, err)) 
     except: 
      print >> sys.stderr, 'Unable to do something: %s' % command 
run_commands(["ls", "echo foo"]) 

>> सिंटैक्स मेरे लिए विशेष रूप से परिचित नहीं है, यह ऐसा कुछ नहीं है जिसे मैं अक्सर उपयोग करता हूं, और मैं समझता हूं कि शायद यह least preferred way है जो stderr को लिखने के लिए है। हालांकि मुझे विश्वास नहीं है कि विकल्प अंतर्निहित समस्या को ठीक करेंगे।

प्रलेखन से मैंने पढ़ा है, IOError 5 को अक्सर दुरुपयोग किया जाता है, और कुछ हद तक परिभाषित किया जाता है, विभिन्न ऑपरेटिंग सिस्टम अलग-अलग समस्याओं को कवर करने के लिए इसका उपयोग करते हैं। मेरे मामले में सबसे अच्छा मैं देख सकता हूं कि पाइथन प्रक्रिया अब टर्मिनल/पीटीआई से जुड़ी नहीं है।

सबसे अच्छा मैं कह सकता हूं कि कुछ भी stdout/stderr धाराओं से प्रक्रिया को डिस्कनेक्ट नहीं कर रहा है - टर्मिनल अभी भी उदाहरण के लिए खुला है, और सबकुछ ठीक दिखता है। क्या यह एक अशुद्ध फैशन में समाप्त होने वाली बाल प्रक्रिया के कारण हो सकता है? इस समस्या का कोई और कारण क्या हो सकता है - या इसे आगे डीबग करने के लिए मैं कौन से अन्य कदम पेश कर सकता हूं?

अपवाद को संभालने के मामले में, मैं स्पष्ट रूप से इसे पकड़ सकता हूं, लेकिन मुझे लगता है कि इसका मतलब है कि मैं निष्पादन के शेष के लिए stdout/stderr पर प्रिंट करने में सक्षम नहीं हूं? क्या मैं इन धाराओं को किसी भी तरह से दोबारा जोड़ सकता हूं - शायद sys.stdout से sys.__stdout__ आदि को रीसेट करके? इस मामले में stdout/stderr को लिखने में सक्षम नहीं होने पर घातक माना जाता है, लेकिन अगर यह गलत होने से शुरू होने का संकेत है तो मैं जल्दी ही जमानत दूंगा।

मुझे लगता है कि अंत में मैं जहां यह एक डिबगिंग शुरू करने के लिए करने के लिए के रूप में एक नुकसान का एक सा यहां हूं ...

+1

मैं देख सकता हूं कि कुछ लोगों ने इस प्रश्न को देखा है, कोई टिप्पणी/उत्तर नहीं। यदि प्रश्न खराब रूप से संरचित/अस्पष्ट है, तो कृपया इसे सुधारने में मेरी सहायता करें ताकि मैं एक उत्तर की ओर काम कर सकूं। –

+0

मैं भी इस त्रुटि को समाप्त कर रहा हूं। कभी-कभी इस त्रुटि को पाने के लिए परेशान करना। –

+1

कुछ उत्तरों के बारे में बुरा मत मानो; आपका प्रश्न और प्रारूप बहुत अच्छा है; जवाब देने के लिए यह एक मुश्किल सवाल है। – culix

उत्तर

5

मैं एक बहुत ही इसी तरह की समस्या थी। मेरे पास एक प्रोग्राम था जो उपप्रोसेसर मॉड्यूल का उपयोग करके कई अन्य कार्यक्रम लॉन्च कर रहा था। उन सबप्रोसेस फिर टर्मिनल पर आउटपुट प्रिंट करेंगे। जो मैंने पाया वह था कि जब मैंने मुख्य कार्यक्रम बंद कर दिया, तो उसने उपप्रोसेस को स्वचालित रूप से समाप्त नहीं किया (जैसा कि मैंने माना था), बल्कि वे चलते रहे। इसलिए यदि मैंने मुख्य कार्यक्रम दोनों को समाप्त कर दिया और फिर टर्मिनल को * से लॉन्च किया गया था, तो उपप्रोसेसेस के पास अब उनके स्टडआउट से जुड़ा टर्मिनल नहीं था, और एक आईओईआरर फेंक देगा। उम्मीद है कि यह आपकी मदद करता है।

* एनबी: यह इस क्रम में किया जाना चाहिए। यदि आप टर्मिनल को मार देते हैं, (किसी कारण से) जो मुख्य कार्यक्रम और उपप्रमुख दोनों को मार देगा।

+1

जो आप वर्णन करते हैं वह मेरी स्थिति के लिए समझ में आता है, हालांकि एक सवाल बनी हुई है। दस्तावेज़ों के मुताबिक, संवाद करने के लिए कॉल() को तब तक पढ़ना चाहिए जब तक कि अंत-फ़ाइल तक नहीं पहुंच जाती है, और उपप्रोसेस को समाप्त करने की प्रतीक्षा करें। चूंकि मुझे सामान्य निष्पादन के दौरान यह त्रुटि मिल रही है (मैं स्वाभाविक रूप से समाप्त करने के लिए माता-पिता और बाल प्रक्रिया दोनों को छोड़ रहा हूं) क्या इसका मतलब यह है कि संवाद() जल्दी लौट रहा है? –

2

मुझे अभी यह त्रुटि मिली है क्योंकि निर्देशिका जहां मैं स्मृति लिखने के लिए फाइलें लिख रहा था। सुनिश्चित नहीं है कि यह आपकी स्थिति के लिए बिल्कुल लागू है या नहीं।

+0

नहीं, दुर्भाग्य से नहीं। डिस्क स्थान की बहुत सारी उपलब्ध है, स्पष्ट रूप से अधिकतम फ़ाइल हैंडल सीमा तक पहुंच नहीं रही है, कम सीपीयू लोड, और कोई स्वैपिंग नहीं है। –

10

मुझे लगता है कि इसे टर्मिनल के साथ प्रक्रिया करना है, प्रक्रिया से जुड़ा हुआ है।जब मैं पृष्ठभूमि में एक अजगर प्रक्रिया को चलाने मैं यह त्रुटि आई और टर्मिनल, जिसमें मैं इसे शुरू कर दिया बंद कर दिया:

$ myprogram.py 
Ctrl-Z 
$ bg 
$ exit 

समस्या यह है कि मैं एक दूरस्थ सर्वर में एक नहीं daemonized प्रक्रिया शुरू कर दी और लॉग आउट (बंद करने था टर्मिनल सत्र)। एक समाधान दूरस्थ सर्वर पर एक स्क्रीन/tmux सत्र शुरू करना था और इस सत्र के भीतर प्रक्रिया शुरू करना था। फिर सत्र को अलग करना + लॉग आउट प्रक्रिया से जुड़े टर्मिनल को रखता है। यह कम से कम * निक्स दुनिया में काम करता है।

0

यह तब हो सकता है जब प्रिंट आपके डेटा को क्रैश करता है जबकि प्रिंट डेटा को लिखने की कोशिश कर रहा था।

0

मैं यहां नया हूं, इसलिए अगर कोड कोड की बात आती है तो कृपया थोड़ा सा फिसल जाए। हाल ही में मैं यह पता लगाने में सक्षम था कि प्रिंट स्टेटमेंट की I/O त्रुटि का कारण क्या है जब पाइथन स्क्रिप्ट के चलने वाले टर्मिनल को बंद कर दिया गया है। ऐसा इसलिए है क्योंकि stdout/stderr पर मुद्रित स्ट्रिंग बहुत लंबी है। इस मामले में, "आउट" स्ट्रिंग अपराधी है। इस समस्या को ठीक करने के लिए (पाइथन स्क्रिप्ट चलाने के दौरान टर्मिनल को खोलने के बिना), लाइन से "आउट" स्ट्रिंग लाइन को पढ़ें, और रेखा से प्रिंट लाइन तक, जब तक हम "आउट" स्ट्रिंग के अंत तक नहीं पहुंच जाते। कुछ ऐसा:

while true: 
     ln=out.readline() 
     if not ln: break 
     print ln.strip("\n") # print without new line 

एक ही समस्या तब होती है जब आप स्क्रीन पर स्ट्रिंग की पूरी सूची मुद्रित करते हैं। बस एक आइटम द्वारा एक आइटम सूची मुद्रित करें। उम्मीद है कि मदद करता है!

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