我怎么能执行蟒蛇ping或路由跟踪,访问输出,因为它是生产出来的?(How can I perfor

2019-06-26 08:04发布

早些时候,我问这个问题:

我怎样才能进行使用本机Python ping或路由跟踪?

但是,由于蟒蛇是不是root运行它好好尝试一下都开到了本机Python执行ping /路由跟踪所需的原料ICMP套接字的能力。

这使我回使用系统的平/ traceroute的shell命令。 这个问题有使用几个例子subprocess模块,它似乎运作良好:

坪Python中的网站吗?

我还是比较有一个要求,虽然我需要能够访问输出,因为它产生(例如,对于长时间运行的traceroute。)

上面的例子都运行shell命令,然后只给你访问到完整的输出,一旦命令完成。 有没有在它制造的访问命令输出的方法吗?

编辑:根据亚历克斯·马尔泰利的答案,这里是什么工作:

import pexpect

child = pexpect.spawn('ping -c 5 www.google.com')

while 1:
        line = child.readline()
        if not line: break
        print line,

Answer 1:

Pexpect的是什么,我想伸手,“默认”,对于任何要求,比如你的-还有其他类似的模块,但Pexpect的几乎都是最富有,最稳定,最成熟的一个。 在一个情况下我会费心寻找替代方案是,如果我不得不在Windows下正常运行过(如ping和跟踪可能有自己的问题,反正) - 让我们知道,如果这是你的情况,我们会看看有什么可以安排 - !)



Answer 2:

你应该阅读的文档子模块,它描述了如何运行外部程序和访问它的实时输出。

基本上,你做

from subprocess import Popen, PIPE
p = Popen(['tracert', host], stdout=PIPE)
while True:
    line = p.stdout.readline()
    if not line:
        break
    # Do stuff with line

其实,在答案SO问你链接到非常接近你所需要的。 科里·戈德堡的答案使用管道和readline ,但由于它运行平与-n 1它不会持续很长时间有所作为。



Answer 3:

您可以创建子进程一个tty对,那里面运行。 根据C标准(C99 7.19.3)中唯一一次标准输出行缓冲(相对于全缓冲这是你说你不想要的)是当它是一个终端。 (或子叫调用setvbuf()很明显)。

退房os.openpty()。

未经测试的代码:

master, slave = os.openpty()
pid = os.fork()
if pid == 0:
    os.close(master)
    os.dup2(slave, 0)
    os.dup2(slave, 1)
    os.dup2(slave, 2)
    os.execv("/usr/sbin/traceroute", ("traceroute","4.2.2.1"))
    # FIXME: log error somewhere
    os.exit(1)
os.close(slave)
while True:
    d = os.read(master)
    if len(d) == 0:
        break
    print d
os.waitpid(pid, 0)

需要注意的是其子进程调用调用setvbuf(只叉()之后)()将无法正常工作,因为调用setvbuf()是libc功能,而不是一个系统调用。 它只是改变当前进程输出,这将在exec调用时加载新的二进制文件被覆盖的状态。



Answer 4:

这是另一种方法:

# const_output.py
import sys
from subprocess import Popen

if len(sys.argv) < 2:
    print 'Usage: const_output.py "command to watch"'
    sys.exit(1)

cmd_line = sys.argv[1:]

p = Popen(cmd_line)
p.communicate()[0]

实例:

路由跟踪:

> python const_output.py traceroute 10.0.0.38
traceroute to 10.0.0.38 (10.0.0.38), 30 hops max, 60 byte packets
 1  10.0.0.38 (10.0.0.38)  0.106 ms  0.023 ms  0.021 ms

平:

> python const_output.py ping 10.0.0.38
PING 10.0.0.38 (10.0.0.38) 56(84) bytes of data.
64 bytes from 10.0.0.38: icmp_seq=1 ttl=64 time=0.046 ms
64 bytes from 10.0.0.38: icmp_seq=2 ttl=64 time=0.075 ms
64 bytes from 10.0.0.38: icmp_seq=3 ttl=64 time=0.076 ms
64 bytes from 10.0.0.38: icmp_seq=4 ttl=64 time=0.073 ms

最佳:

> python const_output.py top
   # you will see the top output


文章来源: How can I perform a ping or traceroute in python, accessing the output as it is produced?