检索 subprocess.call() 的输出

发布于 2024-08-16 20:44:00 字数 810 浏览 7 评论 0原文

如何使用 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'

How can I get the output of a process run using subprocess.call()?

Passing a StringIO.StringIO object to stdout gives this error:

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'

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

紫南 2024-08-23 20:44:00

如果您使用的是 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 以获得相同的结果。

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

If you have Python version 2.7 or later, you can use subprocess.check_output which basically does exactly what you want (it returns standard output as a string).

A simple example (Linux version; see the note):

import subprocess

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

Note that the ping command is using the Linux notation (-c for count). If you try this on Windows, remember to change it to -n for the same result.

As commented below, you can find a more detailed explanation in this other answer.

[旋木] 2024-08-23 20:44:00

subprocess.call() 的输出只能重定向到文件。

您应该使用 subprocess.Popen() 来代替。然后,您可以传递 stderr、stdout 和/或 stdin 参数的 subprocess.PIPE 并使用 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() 方法。仅使用任何类似文件的对象并不能解决问题。

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

Output from subprocess.call() should only be redirected to files.

You should use subprocess.Popen() instead. Then you can pass subprocess.PIPE for the stderr, stdout, and/or stdin parameters and read from the pipes by using the communicate() method:

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

The reasoning is that the file-like object used by subprocess.call() must have a real file descriptor, and thus implement the fileno() method. Just using any file-like object won't do the trick.

See here for more info.

温柔戏命师 2024-08-23 20:44:00

对于 Python 3.5 或更高版本,建议您使用 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)

For Python 3.5 or later, it is recommended that you use the run function from the subprocess module. This returns a CompletedProcess object, from which you can easily obtain the output as well as return code.

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)
幻想少年梦 2024-08-23 20:44:00

我有以下解决方案。它捕获执行的外部命令的退出代码、标准输出和标准错误:

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)

我还有一篇关于它的博客文章 此处

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

I have the following solution. It captures the exit code, the stdout, and the stderr too of the executed external command:

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)

I also have a blog post on it here.

Edit: the solution was updated to a newer one that doesn't need to write to temp. files.

云柯 2024-08-23 20:44:00

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

#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”的文件对象。据我所知,communicate() 方法只是作为一种便捷的方式来返回输出的元组以及您运行的进程中的错误。此外,该进程在实例化 Popen 时运行。

I recently just figured out how to do this, and here's some example code from a current project of mine:

#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 ...

You now have the output of the command stored in the variable "output". "stdout = subprocess.PIPE" tells the class to create a file object named 'stdout' from within Popen. The communicate() method, from what I can tell, just acts as a convenient way to return a tuple of the output and the errors from the process you've run. Also, the process is run when instantiating Popen.

薄荷梦 2024-08-23 20:44:00

关键是使用函数 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")

The key is to use the function subprocess.check_output

For example, the following function captures stdout and stderr of the process and returns that as well as whether or not the call succeeded. It is Python 2 and 3 compatible:

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"])

If you want to pass commands as strings rather than arrays, use this version:

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")
聆听风音 2024-08-23 20:44:00

Ipython shell 中:

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

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

In Ipython shell:

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

Based on sargue's answer. Credit to sargue.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文