【问题标题】:Using python Popen to read the last line使用 python Popen 读取最后一行
【发布时间】:2012-10-31 04:21:42
【问题描述】:

我有一个简单的python程序:

test.py:

import time
for i in range(100000):
    print i
    time.sleep(0.5)

我想使用另一个执行上述程序的程序,以便在上述程序计数时读取最后一行输出。

import subprocess

process = subprocess.Popen("test",stdout=PIPE)
sleep(20) # sleeps an arbitrary time
print stdout.readlines()[-1]

问题是process.stdout.readlines() 一直等到 test.py 完成执行。 有没有办法在程序执行时读取输出中写入的最后一行?

【问题讨论】:

  • 如果您的“测试”程序也是用python编写的,您应该考虑使用线程并将信息从一侧传递到另一侧,而不是从文件中打印和读取...
  • @JBernardo 感谢您的建议,但我试图归档的是让它适用于任何程序。

标签: python stream subprocess pipe


【解决方案1】:

sh.py 相当简单:

import sh

def process_line(line):
    print line

process = sh.python("test.py", _out=process_line)
process.wait()

【讨论】:

    【解决方案2】:

    您可以使用collections.deque 仅保存最后指定的行数:

    #!/usr/bin/env python
    import collections
    import subprocess
    import time
    import threading
    
    def read_output(process, append):
        for line in iter(process.stdout.readline, ""):
            append(line)
    
    def main():
        process = subprocess.Popen(["program"], stdout=subprocess.PIPE)
        # save last `number_of_lines` lines of the process output
        number_of_lines = 1
        q = collections.deque(maxlen=number_of_lines)
        t = threading.Thread(target=read_output, args=(process, q.append))
        t.daemon = True
        t.start()
        #
        time.sleep(20)
    
        # print saved lines
        print ''.join(q),
        # process is still running
        # uncomment if you don't want to wait for the process to complete
        ##process.terminate() # if it doesn't terminate; use process.kill()
        process.wait()
    
    if __name__=="__main__":
        main()
    

    other tail-like solutions that print only the portion of the output

    See here 如果您的子程序在非交互式运行时对其标准输出使用块缓冲(而不是行缓冲)。

    【讨论】:

    • 不错的答案,但遗憾的是我遇到了与我之前所说的相同的问题。它仅在被调用进程完成时才显示输出
    • 我相信test.py Python 正在缓冲发送到sys.stdout 的输出。通过使用-u 标志,我得到了这个解决方案:python -u test.py。 (否则输出为空。)
    • @unutbu:是的。我忘记提了。我添加了提供一些解决方法的链接
    • @AlejandroGarcia:您可以通过将process.terminate() 放在main 的末尾来避免IOError。
    猜你喜欢
    • 2011-04-18
    • 1970-01-01
    • 2016-10-21
    • 2010-09-15
    • 2017-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多