打印时IOError输入/输出错误

时间:2012-05-02 08:05:17

标签: python io stdout ioerror

我继承了一些代码,这些代码由于在打印调用期间引发输入/输出错误而定期(随机)失败。我试图确定引发异常的原因(或至少,更好地理解它)以及如何正确处理它。

执行以下Python行时(在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"])

>>语法对我来说并不是特别熟悉,它不是我经常使用的东西,而且我理解它可能是写入stderr的least preferred way。但是我不相信替代方案会解决潜在的问题。

从我读过的文档中,IOError 5经常被误用,并且有些松散定义,不同的操作系统使用它来覆盖不同的问题。在我的例子中,我能看到的最好的是python进程不再附加到终端/ pty。

我最好不能告诉他们将进程与stdout / stderr流断开连接 - 例如终端仍处于打开状态,并且所有内容都“正常”。这可能是由于子流程以不洁的方式终止而造成的吗?还有什么可能导致这个问题 - 或者我可以引入哪些其他步骤来进一步调试它?

在处理异常方面,我显然可以抓住它,但我假设这意味着我无法打印到stdout / stderr以执行其余的操作?我可以以某种方式重新连接到这些流 - 可能是通过将sys.stdout重置为sys.__stdout__等?在这种情况下,不能写入stdout / stderr不被认为是致命的,但如果它表明一些事情开始出错,我宁愿早点保释。

我想最终我在哪里开始调试这个......我感到有点失落......

7 个答案:

答案 0 :(得分:12)

我认为这与流程附加的终端有关。当我在后台运行python进程并关闭我启动它的终端时,我收到了这个错误:

$ myprogram.py
Ctrl-Z
$ bg
$ exit

问题是我在远程服务器中启动了一个未守护进程并注销(关闭终端会话)。解决方案是在远程服务器上启动screen / tmux会话,并在此会话中启动该进程。然后分离会话+注销会使终端与进程保持关联。这至少在* nix世界中起作用。

答案 1 :(得分:6)

我有一个非常类似的问题。我有一个程序正在使用子进程模块启动其他几个程序。然后,这些子过程将输出打印到终端。我发现当我关闭主程序时,它并没有自动终止子进程(正如我所假设的那样),而是它们一直在运行。因此,如果我终止了主程序,然后它终止了它从*启动,那么子进程不再有一个连接到它们的stdout的终端,并且会抛出一个IOError。希望这会对你有所帮助。

*注意:必须按此顺序完成。如果你只是杀死终端,(由于某种原因)会杀死主程序和子进程。

答案 2 :(得分:2)

我刚收到此错误,因为我写文件的目录已经耗尽了内存。不确定这是否适用于您的情况。

答案 3 :(得分:1)

我是新来的,所以请原谅,如果我在代码细节方面稍微滑了一下。 最近,当能够关闭与python脚本运行相关的终端时,我能够找出导致print语句的I / O错误的原因。 这是因为要打印到stdout / stderr的字符串太长。在这种情况下," out"字符串是罪魁祸首。 要解决这个问题(不必在运行python脚本时保持终端打开),只需阅读" out"逐行打印,逐行打印,直到我们到达" out"串。类似的东西:

Bar.vue

如果将整个字符串列表输出到屏幕,则会出现同样的问题。只需打印一个项目列表。 希望有所帮助!

答案 4 :(得分:0)

当打印机试图将数据写入其中时,shell可能会崩溃。

答案 5 :(得分:0)

对于我来说,我只是重新启动了服务,然后这个问题消失了。现在不为什么了。 我的问题是Odoo遇到了相同的OSError输入/输出错误。

重新启动服务后,它消失了。

答案 6 :(得分:0)

问题是您关闭了 stdout 管道,当调用 print() 时,python 试图写入该管道

这可能是由于使用 & 在后台运行脚本然后关闭终端会话(即关闭 stdout)造成的

$ python myscript.py &
$ exit

一种解决方案是在后台运行时将stdout设置为文件

示例

$ python myscript.py > /var/log/myscript.log 2>&1 &
$ exit

print() 上没有错误