Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/351.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何获取子流程的最后N行';stderr流输出?_Python_Scripting_Subprocess - Fatal编程技术网

Python 如何获取子流程的最后N行';stderr流输出?

Python 如何获取子流程的最后N行';stderr流输出?,python,scripting,subprocess,Python,Scripting,Subprocess,我是一个Python新手,正在编写一个Python(2.7)脚本,该脚本需要执行许多外部应用程序,其中一个将大量输出写入其stderr流。我想弄清楚的是(在Python中)一种简洁的方法,从该子流程的stderr输出流中获取最后N行 目前,我正在从Python脚本运行该外部应用程序,如下所示: p = subprocess.Popen('/path/to/external-app.sh', stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdou

我是一个Python新手,正在编写一个Python(2.7)脚本,该脚本需要执行许多外部应用程序,其中一个将大量输出写入其stderr流。我想弄清楚的是(在Python中)一种简洁的方法,从该子流程的stderr输出流中获取最后N行

目前,我正在从Python脚本运行该外部应用程序,如下所示:

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

我想从其stderr流中捕获最后N行输出,以便将它们写入日志文件或通过电子邮件发送,等等。

如果整个输出无法存储在RAM中,则:

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
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()

谢谢-这工作做得很好!接下来还有一个问题:如果我对匹配(即包含)特定字符串(例如“error”)的最后N行感兴趣,你会如何修改你的答案?stdout中使用的“N”变量在哪里?目前,我从Python脚本运行的外部应用程序没有生成大量的输出,因此我认为我是安全的。但是当我遇到一个应用程序产生了太多的输出时,你的代码看起来非常有用。谢谢