用python doc替换shell管道,我有一段代码像这样。
p1 = Popen(["tac" , "/var/log/some_process_log.output"], stderr=PIPE, stdout=PIPE)
p2 = Popen(["head", "-n", "1000"], stdin=p1.stdout, stdout=outfile)
p1.stdout.close() # Allow p1 to receive a SIGPIPE if p2 exits.
output = p2.communicate()[0]
outfile
是我要重定向head
命令输出的位置。日志文件很大,因此我在上面做一个“头”
链接就像p1 | p2 | p3 | ..... | Pn > outfile
如果执行p1时发生错误,例如用户对/var/log/some_process_log.output
文件没有读取权限,当我执行p1.stderr
Pn.communicate()
中的错误消息
如果我在每个阶段都执行p1.stderr.readline(),则需要long time to process。 pydocs中提到了这一点:
注意:读取的数据缓存在内存中,因此,如果以下情况不要使用此方法 数据大小很大或没有限制。
我避免使用subprocess.check_output,因为它不处理管道并且需要不安全的shell=True
任何帮助将不胜感激。谢谢
答案 0 :(得分:0)
您可以使用以下方法创建单独的管道:
import os
errread, errwrite = os.pipe()
然后将所有stderr
实例的写端设置为Popen
:
p1 = Popen(["tac" , "/var/log/some_process_log.output"], stderr=errwrite, stdout=PIPE)
p2 = Popen(["head", "-n", "1000"], stdin=p1.stdout, stderr=errwrite, stdout=outfile)
记住完成后要关闭写结束:
os.close(errwrite)
并通过以下任一方式获取错误消息:
data_group = os.read(errread, buf_size)
或:
import io
data = io.open(errread, 'rb', buf_size).read()