gpt4 book ai didi

python StringIO 不能作为文件与 subrpocess.call()

转载 作者:太空宇宙 更新时间:2023-11-03 11:53:43 25 4
gpt4 key购买 nike

我正在使用 subprocess 包从 python 脚本调用一些外部控制台命令,我需要将文件处理程序传递给它以获取 stdoutstderr 单独返回。代码大致如下所示:

import subprocess

stdout_file = file(os.path.join(local_path, 'stdout.txt'), 'w+')
stderr_file = file(os.path.join(local_path, 'stderr.txt'), 'w+')

subprocess.call(["somecommand", "someparam"], stdout=stdout_file, stderr=stderr_file)

这工作正常,并且正在创建具有相关输出的 txt 文件。然而,在内存中处理这些输出而忽略文件创建会更好。所以我使用 StringIO 包来处理它:

import subprocess
import StringIO

stdout_file = StringIO.StringIO()
stderr_file = StringIO.StringIO()

subprocess.call(["somecommand", "someparam"], stdout=stdout_file, stderr=stderr_file)

但这行不通。失败:

  File "./test.py", line 17, in <module>
subprocess.call(["somecommand", "someparam"], stdout=stdout_file, stderr=stderr_file)
File "/usr/lib/python2.7/subprocess.py", line 493, in call
return Popen(*popenargs, **kwargs).wait()
File "/usr/lib/python2.7/subprocess.py", line 672, in __init__
errread, errwrite) = self._get_handles(stdin, stdout, stderr)
File "/usr/lib/python2.7/subprocess.py", line 1063, in _get_handles
c2pwrite = stdout.fileno()
AttributeError: StringIO instance has no attribute 'fileno'

我看到它缺少 native 文件对象的某些部分,因此失败了。

所以这个问题更具教育意义而不是实际问题 - 为什么 StringIO 中缺少文件接口(interface)的这些部分,是否有任何原因无法实现?

最佳答案

正如您在评论中所说,PopenPopen.communicate 是正确的解决方案。

一点背景知识:真正的文件对象有文件描述符,也就是fileno属性StringIO对象是缺失的。它们只是普通的整数:您可能熟悉文件描述符 0、1 和 2,它们分别是 stdinstdoutstderr .如果一个进程打开更多文件,它们将被分配 3、4、5 等。您可以使用 lsof -p 查看进程的当前文件描述符。

那么,为什么 StringIO 对象不能有文件描述符呢?为了得到一个,它需要打开一个文件或打开一个管道*。打开文件没有任何意义,因为打开文件是首先使用 StringIO 的全部意义。

并且打开管道也没有意义,即使它们像 StringIO 对象一样存在于内存中。它们用于通信,而不是存储:seektruncatelen 对管道没有任何意义,readwrite 的行为与它们对文件的行为非常不同。当您从管道读取时,返回的数据将从管道的缓冲区中删除,如果当您尝试写入时该(相对较小的)缓冲区已满,您的进程将挂起,直到从管道中读取以释放缓冲区空间。

因此,如果您想将字符串用作子进程的 stdinstdoutstderrStringIO不会削减它,但 Popen.communicate 是完美的。如上所述(并在 subprocess 的文档中警告),正确地读取和写入管道是很复杂的。 Popen 为您处理这种复杂性。

* 我想我理论上可以想象第三种文件描述符对应于进程之间共享的内存区域?不太确定为什么不存在。但是,嗯,我不是内核开发人员,所以我确定这是有原因的。

关于python StringIO 不能作为文件与 subrpocess.call(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19409025/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com