在使用os.system()时,什么会导致出现“IOError: [Errno 9] Bad file descriptor”错误?

86

我正在使用一款科学软件,其中包括一个调用os.system()的Python脚本,用于运行另一个科学程序。在子进程运行时,Python在某个时刻打印了以下内容:

close failed in file object destructor:
IOError: [Errno 9] Bad file descriptor

我认为这条消息与 os.system() 的返回同时打印。

我的问题是:

哪些条件可能导致这种类型的 IOError?它确切地意味着什么?对于由 os.system() 调用的子进程意味着什么?


2
注意:使用subprocess模块比os.system()更可取。 - Petr Viktorin
我知道这个软件有很多不完美的地方。 - Dr. Jan-Philip Gehrcke
3个回答

70

如果一个Python文件不是通过文件对象的close()方法关闭,而是从“外部”关闭,你会收到此错误消息:

>>> f = open(".bashrc")
>>> os.close(f.fileno())
>>> del f
close failed in file object destructor:
IOError: [Errno 9] Bad file descriptor

del f这一行会删除对文件对象的最后一个引用,导致其析构函数 file.__del__被调用。由于从未调用f.close()方法,文件对象的内部状态表明该文件仍处于打开状态,因此析构函数试图关闭文件。随后操作系统抛出错误,因为尝试关闭未打开的文件。

由于os.system()的实现并不会创建任何Python文件对象,因此似乎不太可能是system()调用导致了这个错误。也许你可以展示更多的代码?


1
谢谢。我已经有这个怀疑了。在这一点上展示更多的代码是没有意义的,因为这个Python脚本非常大,结构不好,写得也不好。到目前为止,我还没有很好的概述。在您的帮助下,我将首先尝试自己找到问题。 - Dr. Jan-Philip Gehrcke
1
@Jan-PhilipGehrcke: del f 简单地删除了名称 f,减少了该名称指向的对象的引用计数。如果没有其他引用剩余,则会触发垃圾回收,包括对对象的 __del __() 方法的调用。由于您在 os.system() 调用中收到错误消息,我怀疑这是由于隐式垃圾回收,因此我使用 del 来演示效果。单行 os.close(open(".bashrc").fileno()) 产生相同的错误。 - Sven Marnach
2
如果您正在使用Python 2.6或2.7,可以尝试一个技巧:import io; __builtins__.open = io.open将内置的open()替换为来自io模块的版本(从3.0回溯)。新版本的open()速度较慢,但会忽略文件是否已关闭。 - Sven Marnach
1
@Jan-Philip:是的,如果MPI传递的是操作系统级别的文件描述符而不是Python文件对象,则会出现这种情况。如果您正在使用MPI,我会认为这是非常可能的原因。 - Petr Viktorin
我认为我的问题是在文件仍然打开时没有将一个额外的参数传递到函数中。因此,另一个错误不知何故导致了这个错误。 - Dave Liu
显示剩余6条评论

19
您可能会因为在打开文件时使用错误的模式而遇到此错误。例如:
with open(output, 'wb') as output_file:
    print(output_file.read())

在那段代码中,我想要读取文件,但是我使用了模式wb而不是r或者r+


-1

如果您的勒索软件保护在您的工作目录上启用,则可能会出现此错误。如果目录受到 Windows 自带的勒索软件保护的保护,则 Windows 不允许任何第三方应用程序更改文件。您可以通过转到“Windows 安全性 -> 病毒和威胁防护 -> 管理勒索软件保护 -> 允许应用程序通过受控文件夹访问”来纠正此问题。

然后,通过单击“添加允许的应用程序”添加“Python[version].exe”。


2
各位先生女士,这就是有人通过Python勒索软件脚本如何对您进行敲诈的方式。 - John C.
目前你的回答不够清晰,请编辑并添加更多细节,以帮助其他人理解它如何回答问题。你可以在帮助中心找到有关如何编写好答案的更多信息。 - Community
2
我知道有些人因为安全问题而对此进行了负面评价,但在我的情况下,这确实是导致问题的原因。我只需在运行脚本之前关闭受控文件夹访问权限,然后在脚本完成后立即重新开启即可。 - Darkstar
在我的情况下,我正在运行一个编译后的 Python 应用程序来修改 ini 文件。出于某种原因,在一台计算机上,Windows 安全设置阻止了对这些 ini 文件的文件修改(我的编译应用程序在 ~100 台计算机上运行,但只在其中遇到了这个问题-可能与计算机所有者设置的其他安全设置有关)。将安全性排除路径添加到我的编译应用程序中可以解决该问题。 - Brian K
这也帮助了我。 - Outsider
我一直非常小心确保在我的Mac Ventura上打开了Windows勒索软件保护程序。不幸的是,我仍然遇到了这个错误。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接