我正在使用 python 子进程模块中的 subprocess.check_output 来执行 ping 命令。这是我的做法:
output = subprocess.check_output(["ping","-c 2 -W 2","1.1.1.1")
它引发 CalledProcessError 并表示输出是函数的参数之一。任何人都可以帮助我如何阅读该输出。我想将输出读入字符串并解析它。例如,如果 ping 返回
100%丢包
我需要捕捉到这一点。如果还有其他更好的方法..请建议。谢谢。
根据 Python os 模块文档,自 Python 2.6 起,os.popen 已被弃用。
我认为现代 Python 的解决方案是使用 subprocess 模块中的 check_output()。
subprocess.check_output(args,*,stdin =无,stderr =无,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
您应该看到如下所示的输出:
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']
如果您想恢复 stdout 和 stderr(包括在发生这种情况时从 CalledProcessError 中提取它),请使用以下命令:
import subprocess
def call_with_output(command):
success = False
try:
output = subprocess.check_output(command, stderr=subprocess.STDOUT).decode()
success = True
except subprocess.CalledProcessError as e:
output = e.output.decode()
except Exception as e:
# check_call can raise other exceptions, such as FileNotFoundError
output = str(e)
return(success, output)
call_with_output(["ls", "-l"])
这与 Python 2 和 3 兼容。
如果您的命令是字符串而不是数组,请添加前缀:
import shlex
call_with_output(shlex.split(command))
在参数列表中,每个条目必须独立。使用
output = subprocess.check_output(["ping", "-c","2", "-W","2", "1.1.1.1"])
应该可以解决你的问题。
我遇到了同样的问题,发现文档有此类场景的示例(我们将 STDERR 写入 STDOUT 并始终成功退出并返回代码 0),而不会导致/捕获异常。
output = subprocess.check_output("ping -c 2 -W 2 1.1.1.1; exit 0", stderr=subprocess.STDOUT, shell=True)
现在,您可以使用标准字符串函数
find
来检查输出字符串output
。
Thanx @krd,我正在使用您的错误捕获过程,但必须更新 print 和 except 语句。我在 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
仅当主机响应 ping 时才会返回 true。适用于 Windows 和 Linux
def ping(host):
"""
Returns True if host (str) responds to a ping request.
NB on windows ping returns true for success and host unreachable
"""
param = '-n' if platform.system().lower()=='windows' else '-c'
result = False
try:
out = subprocess.check_output(['ping', param, '1', host])
#ping exit code 0
if 'Reply from {}'.format(host) in str(out):
result = True
except subprocess.CalledProcessError:
#ping exit code not 0
result = False
#print(str(out))
return result