检索 subprocess.call() 的输出[重复]

2024-12-16 08:35:00
admin
原创
125
摘要:问题描述:如何获取使用运行的进程的输出subprocess.call()?传递一个StringIO.StringIO对象会stdout出现以下错误:Traceback (most recent call last): File "<stdin>", line 1, in &...

问题描述:

如何获取使用运行的进程的输出subprocess.call()

传递一个StringIO.StringIO对象会stdout出现以下错误:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/subprocess.py", line 444, in call
    return Popen(*popenargs, **kwargs).wait()
  File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/subprocess.py", line 588, in __init__
    errread, errwrite) = self._get_handles(stdin, stdout, stderr)
  File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/subprocess.py", line 945, in _get_handles
    c2pwrite = stdout.fileno()
AttributeError: StringIO instance has no attribute 'fileno'

解决方案 1:

如果您拥有 Python 2.7 或更高版本,那么您可以使用subprocess.check_output它来基本上完成您想要的操作(它以字符串形式返回标准输出)。

一个简单的例子(Linux版本;见注释):

import subprocess

print subprocess.check_output(["ping", "-c", "1", "8.8.8.8"])

请注意,ping命令使用 Linux 符号 (-c表示计数)。如果您在 Windows 上尝试此操作,请记住将其更改为-n以获得相同的结果。

如下面所评论的,您可以在另一个答案中找到更详细的解释。

解决方案 2:

输出subprocess.call()应该仅重定向到文件。

您应该使用subprocess.Popen()。然后,您可以传递subprocess.PIPEstderr、stdout 和/或 stdin 参数,并使用该方法从管道读取communicate()

from subprocess import Popen, PIPE

p = Popen(['program', 'arg1'], stdin=PIPE, stdout=PIPE, stderr=PIPE)
output, err = p.communicate(b"input data that is passed to subprocess' stdin")
rc = p.returncode

原因是所使用的类文件对象subprocess.call()必须具有真实的文件描述符,因此需要实现该fileno()方法。仅使用任何类文件对象都无法解决问题。

请参阅此处以了解更多信息。

解决方案 3:

对于 Python 3.5 或更高版本,建议使用subprocess 模块中的 run 函数。它将返回一个CompletedProcess对象,您可以从中轻松获取输出以及返回代码。

from subprocess import PIPE, run

command = ['echo', 'hello']
result = run(command, stdout=PIPE, stderr=PIPE, universal_newlines=True)
print(result.returncode, result.stdout, result.stderr)

解决方案 4:

我有以下解决方案。它捕获执行的外部命令的退出代码、stdout 和 stderr:

import shlex
from subprocess import Popen, PIPE

def get_exitcode_stdout_stderr(cmd):
    """
    Execute the external command and get its exitcode, stdout and stderr.
    """
    args = shlex.split(cmd)

    proc = Popen(args, stdout=PIPE, stderr=PIPE)
    out, err = proc.communicate()
    exitcode = proc.returncode
    #
    return exitcode, out, err

cmd = "..."  # arbitrary external command, e.g. "python mytest.py"
exitcode, out, err = get_exitcode_stdout_stderr(cmd)

我在这里也发表了一篇关于该内容的博客文章。

编辑:解决方案已更新为不需要写入临时文件的较新解决方案。

解决方案 5:

我最近刚刚弄清楚如何做到这一点,下面是我当前项目中的一些示例代码:

#Getting the random picture.
#First find all pictures:
import shlex, subprocess
cmd = 'find ../Pictures/ -regex ".*(JPG|NEF|jpg)" '
#cmd = raw_input("shell:")
args = shlex.split(cmd)
output,error = subprocess.Popen(args,stdout = subprocess.PIPE, stderr= subprocess.PIPE).communicate()
#Another way to get output
#output = subprocess.Popen(args,stdout = subprocess.PIPE).stdout
ber = raw_input("search complete, display results?")
print output
#... and on to the selection process ...

现在,命令的输出已存储在变量“output”中。“stdout = subprocess.PIPE”指示类在 Popen 中创建一个名为“stdout”的文件对象。据我所知,communication() 方法只是一种方便的方式来返回输出的元组和您运行的进程的错误。此外,实例化 Popen 时会运行该进程。

解决方案 6:

关键是使用函数subprocess.check_output

例如,以下函数捕获进程的 stdout 和 stderr 并返回该信息以及调用是否成功。它兼容 Python 2 和 3:

from subprocess import check_output, CalledProcessError, STDOUT

def system_call(command):
    """ 
    params:
        command: list of strings, ex. `["ls", "-l"]`
    returns: output, success
    """
    try:
        output = check_output(command, stderr=STDOUT).decode()
        success = True 
    except CalledProcessError as e:
        output = e.output.decode()
        success = False
    return output, success

output, success = system_call(["ls", "-l"])

如果您想将命令作为字符串而不是数组传递,请使用此版本:

from subprocess import check_output, CalledProcessError, STDOUT
import shlex

def system_call(command):
    """ 
    params:
        command: string, ex. `"ls -l"`
    returns: output, success
    """
    command = shlex.split(command)
    try:
        output = check_output(command, stderr=STDOUT).decode()
        success = True 
    except CalledProcessError as e:
        output = e.output.decode()
        success = False
    return output, success

output, success = system_call("ls -l")

解决方案 7:

Ipythonshell 中:

In [8]: import subprocess
In [9]: s=subprocess.check_output(["echo", "Hello World!"])
In [10]: s
Out[10]: 'Hello World!
'

基于萨格的回答。归功于萨尔格。

相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1314  
  随着数字化时代的飞速发展,企业数据成为了核心资产,其安全性至关重要。信创国产电脑作为保障数据安全的关键一环,正逐渐在企业中得到广泛应用。信创国产电脑基于自主研发的技术体系,从硬件到软件都致力于构建安全可靠的环境,为企业数据安全保驾护航。接下来,我们将深入探讨信创国产电脑如何在多个层面提升企业数据安全性。硬件层面的安全保...
什么是信创概念   16  
  随着信息技术的飞速发展,电脑作为重要的办公和生产工具,其性能对于用户的工作效率和体验有着至关重要的影响。在当前信创产业蓬勃发展的背景下,国产电脑逐渐崛起,与进口品牌电脑形成了激烈的竞争态势。了解信创国产电脑与进口品牌在性能方面的差异,对于企业和个人在选择电脑设备时具有重要的指导意义。处理器性能对比处理器是电脑的核心组件...
国产化信创什么意思   16  
  信创国产化适配方案在当前数字化时代具有极其重要的意义。随着全球政治经济形势的变化以及信息技术的飞速发展,实现信息技术的自主可控成为国家和企业的关键需求。信创国产化适配方案旨在将各类信息技术产品和服务进行国产化替代,降低对国外技术的依赖,保障信息安全,推动国内信息技术产业的发展。这不仅关乎国家的信息安全战略,也为国内相关...
信创电脑   17  
  信创国产化操作系统的兴起,是我国信息技术产业发展历程中的一个重要里程碑。随着全球科技竞争的日益激烈,实现信息技术的自主可控成为国家战略的关键部分。国产化操作系统作为信创产业的核心基础,其发展不仅关乎操作系统本身的技术突破,更对整个软件生态产生了深远影响。从底层架构的变革到应用开发模式的转变,从软件企业的发展策略调整到用...
信创国产软件有哪些   13  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用