ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

python StringIO不能用作subrpocess.call()的文件

2019-07-09 00:55:42  阅读:374  来源: 互联网

标签:python file console stringio


我正在使用subprocess包来从python脚本调用一些外部控制台命令,我需要将文件处理程序传递给它以分别获取stdout和stderr.代码大致如下:

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'

我看到它丢失了本机文件对象的某些部分并因此而失败.

所以这个问题更具教育性而非实际性 – 为什么StringIO中缺少文件接口的这些部分,是否有任何原因导致无法实现?

解决方法:

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

一些背景知识:真实文件对象有文件描述符,这是缺少StringIO对象的fileno属性.它们只是普通的整数:你可能熟悉文件描述符0,1和2,它们分别是stdin,stdout和stderr.如果进程打开了更多文件,则会为它们分配3,4,5等.您可以使用lsof -p查看进程的当前文件描述符.

那么,为什么StringIO对象不能有文件描述符?为了获得一个,它需要打开文件或打开管道*.打开文件是没有意义的,因为不首先打开文件就是使用StringIO的重点.

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

因此,如果您想将字符串用作stdin,stdout或stderr作为子进程,StringIO将不会删除它,但Popen.communicate是完美的.如上所述(并在子流程的文档中警告),正确读取和写入管道是复杂的. Popen为您处理这种复杂性.

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

标签:python,file,console,stringio
来源: https://codeday.me/bug/20190709/1407763.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有