簡體   English   中英

在運行過程中如何獲取子進程輸出?

[英]How to get subprocess output during its running?

我有2個文件main.py和infinit.py,如下所示:

main.py

#!/usr/bin/python

import logging
import subprocess
import sys

logging.basicConfig(level=logging.INFO)


def forever():
    cmd = [sys.executable, 'infinit.py']
    while 1:
        try:
            print 'running new instance of:'
            print ' '.join(cmd)
            popen = subprocess.Popen(cmd, stdout=subprocess.PIPE,
                stderr=subprocess.PIPE, universal_newlines=True)

            for line in iter(popen.stderr.readline, ""):
                print line,
            for line in iter(popen.stdout.readline, ""):
                print line,

        except Exception as e:
            print 'Something bad happend'
            logging.error(e)


if __name__ == '__main__':
    forever()

無窮大

#!/usr/bin/python

import logging

logging.basicConfig(level=logging.INFO)

i = 0
while 1:
    i += 1
    logging.info('i: {0}'.format(i))
    print i

我運行main.py,我想在控制台中同時看到(打印和日志記錄)。 我也希望它在Windows和Linux上運行。 另外,它是否可以在Windows空閑狀態下工作(打印和記錄)?

在程序開始時添加此行,並輸入相同的LOG_FILENAME,然后可以使用tail -f unix命令查看輸出。

import logging
logging.basicConfig(filename=LOG_FILENAME,level=logging.DEBUG, filemode = 'w+')
logging.getLogger().setLevel(logging.DEBUG)

我發現了兩個解決方案,它們都可以在Linux和Windows甚至Windows Idle上運行:

  1. 簡單的:

在父進程中,打印子進程的stderr:

#!/usr/bin/python

import logging
import subprocess
import sys

def forever():
    cmd = [sys.executable, 'infinit.py']
    while 1:
        try:
            print 'running new instance of:'
            print ' '.join(cmd)
            popen = subprocess.Popen(cmd, stdout=subprocess.PIPE,
                stderr=subprocess.PIPE, universal_newlines=True)

            for line in iter(popen.stderr.readline, ""):
                print line,

        except Exception as e:
            print 'Something bad happend'
            logging.error(e)

if __name__ == '__main__':
    forever()

目前:

  • 父級打印子級日志記錄(因為默認情況下,日志記錄會向我們正在打印的stderr adn stderr發送消息)
  • 家長不打印兒童印刷品,因此:

無窮大

#!/usr/bin/python

import logging
import sys
import time

logging.basicConfig(level=logging.INFO)

sys.stdout = sys.stderr

i = 0
while 1:
    i += 1
    logging.info('i: {0}'.format(i))
    print i
    time.sleep(0.2)
  1. 另一個方法是在這里:

在子進程運行時攔截它的stdout

我的代碼適應了解決方案

main.py

#!/usr/bin/python

import logging
import subprocess
import sys

def forever():
    CMD = [sys.executable, 'infinit.py']
    while 1:
        try:
            print 'running new instance of:'
            print ' '.join(CMD)

            popen = subprocess.Popen(CMD, stdout=subprocess.PIPE)
            for line in iter(popen.stdout.readline, ""):
                print line,

        except Exception as e:
            print 'Something bad happend'
            logging.error(e)
        finally:
            print


if __name__ == '__main__':
    forever()

inifinit.py

#!/usr/bin/python

import logging
import sys
import time


class FlushFile(object):
    """Write-only flushing wrapper for file-type objects."""
    def __init__(self, f):
        self.f = f
    def write(self, x):
        self.f.write(x)
        self.f.flush()

logging.basicConfig(level=logging.INFO)

sys.stdout = FlushFile(sys.stdout)


i = 0
while 1:
    i += 1
    logging.info('i: {0}'.format(i))
    print i
    time.sleep(0.2)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM