How to get the last N lines of a subprocess' stderr stream output?

匿名 (未验证) 提交于 2019-12-03 01:05:01

问题:

I am a Python newbie writing a Python (2.7) script that needs to exec a number of external applications, one of which writes a lot of output to its stderr stream. What I am trying to figure out is a concise and succinct way (in Python) to get the last N lines from that subprocess' stderr output stream.

Currently, I am running that external application from my Python script like so:

p = subprocess.Popen('/path/to/external-app.sh', stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = p.communicate()  if p.returncode != 0:     print "ERROR: External app did not complete successfully (error code is " + str(p.returncode) + ")"     print "Error/failure details: ", stderr     status = False else:     status = True

I'd like to capture the last N lines of output from its stderr stream so that they can be written to a log file or emailed, etc.

回答1:

N = 3 # for 3 lines of output p = subprocess.Popen(['/path/to/external-app.sh'],      stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = p.communicate()  if p.returncode != 0:     print ("ERROR: External app did not complete successfully "            "(error code is %s)" % p.returncode)     print "Error/failure details: ", '\n'.join(stderr.splitlines()[-N:])     status = False else:     status = True


回答2:

If the whole output can't be stored in RAM then:

import sys  from collections import deque from subprocess  import Popen, PIPE from threading   import Thread  ON_POSIX = 'posix' in sys.builtin_module_names  def start_thread(func, *args):     t = Thread(target=func, args=args)     t.daemon = True     t.start()     return t  def consume(infile, output):     for line in iter(infile.readline, ''):         output(line)     infile.close()  p = Popen(['cat', sys.argv[1]], stdout=PIPE, stderr=PIPE,           bufsize=1, close_fds=ON_POSIX)  # preserve last N lines of stdout,  print stderr immediately N = 100  queue = deque(maxlen=N) threads  = [start_thread(consume, *args)             for args in (p.stdout, queue.append), (p.stderr, sys.stdout.write)] for t in threads: t.join() # wait for IO completion  print ''.join(queue), # print last N lines retcode = p.wait()


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!