如何在运行期间获得子进程输出?

时间:2012-10-29 16:26:09

标签: python windows subprocess

我有两个文件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()

infinit.py

#!/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 Idle中工作(打印和记录)吗?

2 个答案:

答案 0 :(得分:0)

在程序开头添加这些行,并放置相同的LOG_FILENAME,然后可以使用tail -f unix命令查看输出。

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

答案 1 :(得分:0)

我找到了两个解决方案,两个解决方案都适用于Linux和Windows,甚至适用于Windows Idle:

  1. 更简单:
  2. 在父进程中打印子进程的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)
    • 父母不打印儿童打印,所以:

    infinit.py

    #!/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. 另一个approch在这里:
    2. Intercepting stdout of a subprocess while it is running

      我的代码适应了解决方案

      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)