检查CalledProcessError的输出

ash*_*ash 42 python subprocess

我正在使用pythons子进程模块中的subprocess.check_output来执行ping命令.我是这样做的:

output = subprocess.check_output(["ping","-c 2 -W 2","1.1.1.1")
Run Code Online (Sandbox Code Playgroud)

它引发了一个CalledProcessError,并说输出是函数的参数之一.任何人都可以帮我如何阅读该输出.我想将输出读入一个字符串并解析它.例如,如果ping返回,请说

100%丢包

我需要抓住它.如果有任何其他更好的方法..请建议.谢谢.

krd*_*krd 152

根据Python os模块文档,自Python 2.6以来,os.popen已被弃用.

我认为现代Python的解决方案是使用子进程模块中的check_output().

子进程Python文档:

subprocess.check_output(args,*,stdin = None,stderr = None,shell = False,universal_newlines = False)运行带参数的命令并将其输出作为字节字符串返回.

如果返回码非零,则会引发CalledProcessError.CalledProcessError对象将具有returncode属性中的返回代码以及output属性中的任何输出.

如果您在Python 2.7(或更高版本)中运行以下代码:

import subprocess

try:
    print subprocess.check_output(["ping", "-n", "2", "-w", "2", "1.1.1.1"])
except subprocess.CalledProcessError, e:
    print "Ping stdout output:\n", e.output
Run Code Online (Sandbox Code Playgroud)

你应该看到一个看起来像这样的输出:

Ping stdout output:

Pinging 1.1.1.1 with 32 bytes of data:
Request timed out.
Request timed out.

Ping statistics for 1.1.1.1:
Packets: Sent = 2, Received = 0, Lost = 2 (100% loss),
Run Code Online (Sandbox Code Playgroud)

可以解析e.output字符串以满足OP的需要.

如果你想要返回码或其他属性,它们都在CalledProccessError中,可以通过pdb单步执行看到

(Pdb)!dir(e)   

['__class__', '__delattr__', '__dict__', '__doc__', '__format__',
 '__getattribute__', '__getitem__', '__getslice__', '__hash__', '__init__',
 '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__',
 '__setattr__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__', 
 '__unicode__', '__weakref__', 'args', 'cmd', 'message', 'output', 'returncode']
Run Code Online (Sandbox Code Playgroud)

  • 注意:如果不使用输出,请使用`check_call`而不是`check_output`.如果你知道命令在普通情况下返回非零退出状态,那么你可以直接使用`p = Popen()`并调用`p.wait()`或`output,err = p.communicate()`(如果你需要输出)以避免引起不必要的异常 (3认同)
  • 感谢包装尝试除外. (2认同)

Zag*_*ags 20

如果您想返回 stdout 和 stderr(包括在发生的情况下从 CalledProcessError 中提取它),请使用以下命令:

import subprocess

command = ["ls", "-l"]
try:
    output = subprocess.check_output(command, stderr=subprocess.STDOUT).decode()
    success = True 
except subprocess.CalledProcessError as e:
    output = e.output.decode()
    success = False

print(output)
Run Code Online (Sandbox Code Playgroud)

这是 Python 2 和 3 兼容的。

如果您的命令是字符串而不是数组,请在其前面加上:

import shlex
command = shlex.split(command)
Run Code Online (Sandbox Code Playgroud)


phi*_*hag 13

在参数列表中,每个条目必须独立.运用

output = subprocess.check_output(["ping", "-c","2", "-W","2", "1.1.1.1"])
Run Code Online (Sandbox Code Playgroud)

应该解决你的问题.

  • 这不能回答问题。 (5认同)
  • @ash,jfyi应该是`除了subprocess.CalledProcessError` (3认同)