2012-05-02 32 views
18

Tôi đã kế thừa một số mã định kỳ (ngẫu nhiên) không thành công do lỗi đầu vào/đầu ra được đưa ra trong khi gọi để in. Tôi đang cố gắng xác định nguyên nhân của ngoại lệ được nêu ra (hoặc ít nhất, hiểu rõ hơn về nó) và cách xử lý nó một cách chính xác.Lỗi đầu vào/đầu ra IOError khi in

Khi thực hiện dòng sau của Python (trong một phiên dịch 2.6.6, chạy trên CentOS 5.5):

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

Trường hợp ngoại lệ được nâng lên (traceback bỏ qua):

IOError: [Errno 5] Input/output error 

Đối với bối cảnh , đây thường là chức năng lớn hơn đang cố gắng thực hiện tại thời điểm đó:

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"]) 

>> cú pháp không phải là đặc biệt quen thuộc với tôi, nó không phải cái gì tôi sử dụng thường xuyên, và tôi hiểu rằng nó có lẽ là least preferred way của văn bản để stderr. Tuy nhiên tôi không tin rằng các giải pháp thay thế sẽ khắc phục được vấn đề cơ bản.

Từ tài liệu tôi đã đọc, IOError 5 thường bị lạm dụng và được định nghĩa một cách lỏng lẻo, với các hệ điều hành khác nhau sử dụng nó để giải quyết các vấn đề khác nhau. Điều tốt nhất tôi có thể thấy trong trường hợp của tôi là quá trình python không còn được gắn với terminal/pty nữa.

Tốt nhất tôi không thể nói không có gì đang ngắt kết nối quy trình khỏi luồng stdout/stderr - thiết bị đầu cuối vẫn mở ví dụ và mọi thứ 'xuất hiện' sẽ ổn. Nó có thể được gây ra bởi quá trình con chấm dứt trong một thời trang ô uế? Điều gì khác có thể là nguyên nhân của vấn đề này - hoặc tôi có thể giới thiệu các bước nào khác để gỡ lỗi thêm?

Về mặt xử lý ngoại lệ, tôi rõ ràng có thể bắt được nó, nhưng tôi giả định điều này có nghĩa là tôi sẽ không thể in ra stdout/stderr cho phần còn lại của việc thực thi? Tôi có thể gắn lại các luồng này bằng cách nào đó - có lẽ bằng cách đặt lại sys.stdout thành sys.__stdout__ v.v. Trong trường hợp này không thể ghi vào stdout/stderr không được coi là gây tử vong nhưng nếu nó là một dấu hiệu của một cái gì đó bắt đầu đi sai tôi muốn bảo lãnh sớm.

Tôi đoán cuối cùng tôi đang ở một chút mất mát về vị trí bắt đầu gỡ lỗi này ...

+1

Tôi chỉ có thể thấy một vài người đã xem câu hỏi này, không có nhận xét/câu trả lời. Nếu câu hỏi có cấu trúc kém/không rõ ràng, hãy giúp tôi cải thiện nó để tôi có thể hướng tới câu trả lời. –

+0

Tôi cũng đang xử lý lỗi này. Vì vậy, gây phiền nhiễu để có được lỗi này đôi khi. –

+1

Đừng cảm thấy xấu về vài câu trả lời; câu hỏi và định dạng của bạn thật tuyệt vời; đây chỉ đơn giản là một câu hỏi khó trả lời. – culix

Trả lời

5

Tôi gặp vấn đề tương tự. Tôi đã có một chương trình đã được tung ra một số chương trình khác bằng cách sử dụng mô-đun subprocess. Những quy trình con sau đó sẽ in ra đầu ra. Những gì tôi thấy là khi tôi đóng chương trình chính, nó không tự động chấm dứt các quy trình con (như tôi đã giả định), thay vào đó chúng tiếp tục chạy. Vì vậy, nếu tôi chấm dứt cả hai chương trình chính và sau đó các thiết bị đầu cuối nó đã được đưa ra từ *, các quy trình con không còn có một thiết bị đầu cuối gắn liền với stdout của họ, và sẽ ném một IOError. Hy vọng điều này sẽ giúp bạn.

* NB: nó phải được thực hiện theo thứ tự này. Nếu bạn chỉ cần giết thiết bị đầu cuối, (vì một lý do nào đó) sẽ giết cả chương trình chính và các quy trình con.

+1

Những gì bạn mô tả có ý nghĩa cho tình hình của tôi, tuy nhiên vẫn còn một câu hỏi. Theo các tài liệu, lời gọi để giao tiếp() nên đọc cho đến khi kết thúc tập tin, và chờ cho tiến trình con chấm dứt. Khi tôi nhận được lỗi này trong quá trình thực hiện bình thường (tôi để lại cả quá trình cha và con để chấm dứt một cách tự nhiên), điều đó có nghĩa là giao tiếp() trả về sớm? –

2

Tôi vừa gặp lỗi này vì thư mục mà tôi đang viết tệp để hết bộ nhớ. Không chắc chắn nếu điều này là ở tất cả áp dụng cho tình hình của bạn.

+0

Không, rất tiếc là không. Rất nhiều không gian đĩa có sẵn, dường như không đạt đến giới hạn xử lý tệp tối đa, tải cpu thấp và không trao đổi. –

10

Tôi nghĩ rằng nó phải làm với các thiết bị đầu cuối quá trình được gắn vào.Tôi đã nhận lỗi này khi tôi chạy một quá trình trăn ở chế độ nền và đóng cửa nhà ga, trong đó tôi bắt đầu nó:

$ myprogram.py 
Ctrl-Z 
$ bg 
$ exit 

Vấn đề là tôi bắt đầu một quá trình không daemonized trong một máy chủ từ xa và đăng xuất khỏi (đóng phiên đầu cuối). Một giải pháp là bắt đầu một phiên màn hình/tmux trên máy chủ từ xa và bắt đầu quá trình trong phiên này. Sau đó, tách phiên + đăng xuất sẽ giữ thiết bị đầu cuối được kết hợp với quy trình. Điều này làm việc ít nhất trong thế giới * nix.

0

Điều này có thể xảy ra khi vỏ của bạn bị treo khi in đang cố ghi dữ liệu vào đó.

0

Tôi mới ở đây, vì vậy hãy tha thứ nếu tôi đề cập đến một chút khi nói đến chi tiết mã. Gần đây tôi đã có thể tìm ra nguyên nhân gây ra lỗi I/O của lệnh in khi thiết bị đầu cuối liên quan đến việc chạy tập lệnh python bị đóng. Đó là vì chuỗi được in thành stdout/stderr quá dài. Trong trường hợp này, chuỗi "out" là thủ phạm. Để khắc phục vấn đề này (không cần phải giữ thiết bị đầu cuối mở trong khi chạy tập lệnh python), chỉ cần đọc chuỗi "out" theo dòng, và in từng dòng một, cho đến khi chúng ta kết thúc chuỗi "out". Một cái gì đó như:

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

Cùng một vấn đề xảy ra nếu bạn in toàn bộ danh sách chuỗi ra màn hình. Chỉ cần in danh sách một mục theo một mục. Hy vọng rằng sẽ giúp!

Các vấn đề liên quan