在Python中实时读取subprocess标准输出
我程序中的一个函数会检查一个文件的md5值。
def check():
print "checking integrity status.."
md5 = subprocess.Popen(["md5sum", "-c", hashfile],shell=False, stdout=subprocess.PIPE)
#fopen = open(basefile, "r")
for f in md5.stdout.readlines():
fc = f.rstrip("\n")
sys.stdout.write("\rChecking..." + fc)
sys.stdout.flush()
现在的问题是,整个命令会先执行完,然后for循环再通过md5.stdout.readlines来读取md5的输出。这样就不是动态的,也就是说我不能在命令执行的时候就看到输出……有没有办法让我在命令执行的同时就能看到输出呢……
根据glglgl的回答解决了这个问题:
def check():
print "checking integrity status.."
md5 = subprocess.Popen(["md5sum", "-c", hashfile],shell=False, stdout=subprocess.PIPE)
#fopen = open(basefile, "r")
fc = "NULL"
i = 0
for f in iter(md5.stdout.readline, ''):
k = fc
fc = f.rstrip("\n")
if "FAILED" in fc:
print fc
i = i + 1
sys.stdout.write("\rChecking... "+ str(i)+ " " + fc + (' ' * (len(k) - len(fc))) )
sys.stdout.flush()
3 个回答
0
文件大小是多少?
Popen会创建一个新的子进程来执行命令。可能在你运行循环之前,它就已经完成了。
你可以通过查看“subprocess”的返回码来检查它是否已经完成(在你的代码中是:md5.returncode)。
1
发帖的人说得对,hashlib这个库在Python 2.4里是没有的,不过md5这个库是可以用的。下面是一个解决方法的例子:
try:
# Python 2.5 and up.
import hashlib
md5Hash = hashlib.md5
except ImportError:
# Python 2.4 and below.
import md5
md5Hash = md5.new
somedata = 'foobar'
hashstring = md5Hash (somedata).hexdigest ()
5
当然可以。有几种方法可以做到这一点。
首先,你可以使用
md5.stdout.read()
,不过这样的话你需要自己处理每一行的分隔。接着,你可以把文件对象
md5.stdout
当作一个迭代器来使用。但这里似乎有个缓冲的问题,也就是说你不会立刻得到结果。还有一种方法是反复调用
md5.stdout.readline()
,直到它返回''
(空字符串)。
在这种情况下,第三种方法是比较推荐的;我建议你这样做:
...
for f in iter(md5.stdout.readline, ''):
fc = f.rstrip("\n")
sys.stdout.write("\rChecked " + fc)
sys.stdout.flush()
我也修改了输出文本,因为只有在检查完成后才会有输出。
如果你想要的不是这样,而是希望每次输出都单独捕获,那你应该选择第一种方法。但这样会让事情变得更复杂。我会考虑一个解决方案,如果有人需要的话。
在这里,需要考虑以下几点:
read()
是阻塞的,所以最好一个字节一个字节地读取(这有点麻烦)。- 还有一个问题是,什么内容应该输出,以及什么时候应该有中间输出。