我想计算用stdout
创建的进程(此处为unrar.exe)写入Popen
的行数。
import time
from subprocess import Popen, PIPE, STDOUT
p = Popen('unrar.exe x -y myfile.rar', stdout=PIPE)
while (p is not finished): # pseudo code here and next lines...
time.sleep(0.100)
print 'Number of lines written to STDOUT by unrar' + len(PIPE.split('\n'))
如何正确执行此操作?
备注:我已经查看了p.communicate()
(https://python.readthedocs.org/en/v2.7.2/library/subprocess.html#subprocess.Popen.communicate),但这会阻止执行Python,直到p
终止,不是我想要的:我希望能够在p
运行时打印{{1}}所写的行数。
答案 0 :(得分:1)
我正在寻找一个更简单的解决方案而不使用其他线程等。我不介意这个过程是否每100毫秒被阻止
如果要求进程不能阻塞,则需要线程(或其他异步技术)。要模仿非阻塞wc --lines <(cmd)
:
#!/usr/bin/env python
import io
import shlex
from functools import partial
from subprocess import Popen, PIPE
from threading import Thread
from Queue import Queue
def count_lines(pipe, queue, chunksize=io.DEFAULT_BUFFER_SIZE):
#NOTE: you could write intermediate results here (just drop `sum()`)
queue.put(sum(chunk.count(b'\n')
for chunk in iter(partial(pipe.read, chunksize), b'')))
pipe.close()
p = Popen(shlex.split('unrar.exe x -y myfile.rar'), stdout=PIPE, bufsize=-1)
result = Queue()
Thread(target=count_lines, args=[p.stdout, result]).start()
p.wait() # you can omit it if you want to do something else and call it later
number_of_lines = result.get() # this blocks (you could pass `timeout`)
另一方面,如果你只需要“来打印p写的行数 运行。“然后你可以计算主线程中的行数:
#!/usr/bin/env python
import shlex
from subprocess import Popen, PIPE
p = Popen(shlex.split('unrar.exe x -y myfile.rar'), stdout=PIPE, bufsize=1)
count = 0
for line in iter(p.stdout.readline, b''):
count += 1
print count
p.stdout.close()
p.wait()
答案 1 :(得分:0)
我不知道这是否是最干净的方式,但它确实有效:
from subprocess import Popen, PIPE
import io, time
p = Popen('unrar.exe x -y myfile.rar', stdout = PIPE)
b = ' '
i = 0
while b:
b = p.stdout.readline()
i += 1
print i
print 'FINISHED'