2011-09-27 49 views
30

我使用python子进程模块中的subprocess.check_output执行ping命令。这里是我正在做它:检查来自CalledProcessError的输出

output = subprocess.check_output(["ping","-c 2 -W 2","1.1.1.1") 

它养CalledProcessError并说输出的函数的参数之一。任何人都可以帮助我如何阅读输出。我想将输出读入一个字符串并解析它。所以说,例如如果ping返回

100%的丢包

我需要捕获。如果还有其他更好的方法..请提出建议。谢谢。

+1

//,你会在这个问题中包含一个指向这个文档的链接,https://docs.python.org/2/library/subprocess.html#subprocess.CalledProcessError? –

回答

10

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

output = subprocess.check_output(["ping", "-c","2", "-W","2", "1.1.1.1"]) 

应该解决您的问题。

+0

我仍然收到错误。该错误表示输出是CalledProcessError的参数之一。我尝试使用除...之外的尝试,但也没有工作。 – ash

+0

@ash你能发表一个[可重复使用的简短示例](http://sscce.org/),说明'except'不能正常工作吗? – phihag

+1

尝试:除CalledProcessError外的子处理.check_output([“ping”,“-c”,“2”,“-W”,“2”,“1.1.1.1”)如e:print str(e.output)。这是我的尝试catch块 – ash

127

根据Python os module documentation os.popen自Python 2.6以来已被弃用。

我认为现代Python的解决方案是使用来自子流程模块的check_output()。

subprocess Python documentation

subprocess.check_output(参数,*,标准输入=无,标准错误=无,壳=假,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 

你应该看到的输出,看起来是这样的:

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), 

的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'] 
+0

完美答案+1 –

+2

注意:如果不使用输出,请使用'check_call'而不是'check_output'。如果您知道该命令在普通情况下返回非零退出状态,那么您可以直接使用'p = Popen()'并调用'p.wait()'或'output,err = p.communicate()'(if你需要输出)来避免引发不必要的异常 – jfs

+0

@JFSebastian我尝试使用subprocess.call,但是这会返回一个int(1)而不是我的命令的输出:/ – Loretta

0

感谢名单@krd步进通过,我使用你的错误捕获过程可以看出,但不得不更新打印和除外声明。我在Linux Mint 17.2上使用Python 2.7.6。

另外,还不清楚输出字符串来自哪里。 我的更新:

import subprocess 

# Output returned in error handler 
try: 
    print("Ping stdout output on success:\n" + 
      subprocess.check_output(["ping", "-c", "2", "-w", "2", "1.1.1.1"])) 
except subprocess.CalledProcessError as e: 
    print("Ping stdout output on error:\n" + e.output) 

# Output returned normally 
try: 
    print("Ping stdout output on success:\n" + 
      subprocess.check_output(["ping", "-c", "2", "-w", "2", "8.8.8.8"])) 
except subprocess.CalledProcessError as e: 
    print("Ping stdout output on error:\n" + e.output) 

我看到像这样的输出:

Ping stdout output on error: 
PING 1.1.1.1 (1.1.1.1) 56(84) bytes of data. 

--- 1.1.1.1 ping statistics --- 
2 packets transmitted, 0 received, 100% packet loss, time 1007ms 


Ping stdout output on success: 
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data. 
64 bytes from 8.8.8.8: icmp_seq=1 ttl=59 time=37.8 ms 
64 bytes from 8.8.8.8: icmp_seq=2 ttl=59 time=38.8 ms 

--- 8.8.8.8 ping statistics --- 
2 packets transmitted, 2 received, 0% packet loss, time 1001ms 
rtt min/avg/max/mdev = 37.840/38.321/38.802/0.481 ms 
0

如果你想获得输出和错误背部(包括一个发生,则来自CalledProcessError提取它),使用如下:

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

这是Python 2和3兼容。

如果您的命令是一个字符串,而不是一个数组,前缀是:

import shlex 
command = shlex.split(command) 
0

我遇到了同样的问题,发现documentation有例如对于这种类型的情况下(这是我们写错误输出到STDOUT,并且总是以返回代码0成功退出),而不引起/捕获异常。现在

output = subprocess.check_output("ping -c 2 -W 2 1.1.1.1; exit 0", stderr=subprocess.STDOUT, shell=True) 

,你可以使用标准的字符串函数find检查输出字符串output