1 python2
#! -*- coding: utf-8 -*-
import os
import fcntl
import subprocess
import time
def non_block_read(output):
fd = output.fileno()
fl = fcntl.fcntl(fd, fcntl.F_GETFL)
fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)
def test():
cmdline = "ping 127.0.0.1 -w 5"
cmdlist = cmdline.split()
p = subprocess.Popen(cmdlist, shell=False, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
non_block_read(p.stdout) # 避免stdout中没有结果时读会阻塞,此种方法可能会丢失一些结果信息
resinfo = ""
while True:
try:
resinfo = p.stdout.readline() # 1 读时不会阻塞; 2 当stdout中没有结果时会出现异常; 3 当所有结果已取完后再次取的时候会取到空字符串。
except Exception as e:
resinfo = None
if resinfo:
print(resinfo)
if resinfo is not None and resinfo == "":
break
if __name__ == "__main__":
test()
"""
运行结果:
PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.015 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.026 ms
64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.026 ms
64 bytes from 127.0.0.1: icmp_seq=4 ttl=64 time=0.026 ms
64 bytes from 127.0.0.1: icmp_seq=5 ttl=64 time=0.024 ms
--- 127.0.0.1 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4002ms
rtt min/avg/max/mdev = 0.015/0.023/0.026/0.006 ms
"""
2 python3
import os
import fcntl
import subprocess
import time
def non_block_read(output):
fd = output.fileno()
fl = fcntl.fcntl(fd, fcntl.F_GETFL)
fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)
def test():
cmdline = "ping 127.0.0.1 -w 5"
cmdlist = cmdline.split()
p = subprocess.Popen(cmdlist, shell=False, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
non_block_read(p.stdout) # 避免stdout中没有结果时读会阻塞,此种方法可能会丢失一些结果信息
resinfo = ""
while True:
resinfo = p.stdout.readline().decode("utf-8") # 1 读时不会阻塞; 2 当stdout中没有结果时取到空字符串,注意与python2的不同。
if resinfo:
print(resinfo)
completed = p.poll() # 命令执行完成时poll()会返回一个数字,0表示执行成功,非0表示执行失败;命令正在执行过程中poll()会返回None
if completed is not None:
resinfo = p.stdout.readline().decode("utf-8") # 虽然命令已执行完但stdout中的结果可能还没取完
if not resinfo:
break
print(resinfo)
time.sleep(0.5)
if __name__ == "__main__":
test()
"""
运行结果:
PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.014 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.022 ms
64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.016 ms
64 bytes from 127.0.0.1: icmp_seq=4 ttl=64 time=0.024 ms
64 bytes from 127.0.0.1: icmp_seq=5 ttl=64 time=0.022 ms
64 bytes from 127.0.0.1: icmp_seq=6 ttl=64 time=0.025 ms
--- 127.0.0.1 ping statistics ---
6 packets transmitted, 6 received, 0% packet loss, time 4999ms
rtt min/avg/max/mdev = 0.014/0.020/0.025/0.006 ms
"""
3 python3
建议使用以下异步的方式
import threading
import subprocess
import time
def test():
cmdline = "ping 127.0.0.1 -w 5"
cmdlist = cmdline.split()
p = subprocess.Popen(cmdlist, shell=False, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True)
while True:
resinfo = p.stdout.readline() # 1 读时不会阻塞; 2 当stdout中没有结果时取到空字符串,注意与python2的不同。
if resinfo:
print(resinfo)
completed = p.poll() # 命令执行完成时poll()会返回一个数字,0表示执行成功,非0表示执行失败;命令正在执行过程中poll()会返回None
if completed is not None:
resinfo = p.stdout.readline() # 虽然命令已执行完但stdout中的结果可能还没取完
if not resinfo:
break
print(resinfo)
time.sleep(0.5)
if __name__ == "__main__":
thr = threading.Thread(target=test)
thr.setDaemon(True)
thr.start()
thr.join() # 在业务代码中这行需要注掉,不能阻塞主线程往下执行