带python子流程的实时管道。检查\u输出或解决方案?
我的一个大型项目的一部分包括一个python部分,如下所示:带python子流程的实时管道。检查\u输出或解决方案?,python,subprocess,pipe,Python,Subprocess,Pipe,我的一个大型项目的一部分包括一个python部分,如下所示: failcount = 0 done = False while done == False: try: result = subprocess.check_output(program) done = True except subprocess.CalledProcessError as e: failcount += 1 logwrite('logf
failcount = 0
done = False
while done == False:
try:
result = subprocess.check_output(program)
done = True
except subprocess.CalledProcessError as e:
failcount += 1
logwrite('logfile.txt', 'Failed. Counter = {0}\nError message: {1}\n-'.format(failcount, e.returncode))
if failcount == 20:
print 'It failed 20 times, aborting...'
quit()
这意味着要从命令行运行“程序”。“程序”是一个大型计算化学软件包,有时会失败,所以我在这里循环运行它。如果失败20次,那么我的python脚本将终止。这工作得很好,它实现了预期目标。然而,我的问题是,我的化学包每次尝试大约需要三个小时,我想在进行过程中监控它
如果我从命令行手动运行它,我可以简单地执行“program>logfile”,然后跟踪日志文件以观察它的运行。但是,在python中似乎无法执行以下操作:
subprocess.check_output(['program', '>', 'logfile'])
有没有一种方法可以让python在填充subprocess.check_输出时打印出它的内容?我认为subprocess.check_输出只包含标准输出中的内容。我可以在python和管道之间克隆它吗
可能的解决方法:我制作了一个名为run_program.sh的bash脚本,它只执行上面列出的program>logfile,然后使用python的子进程执行run_program.sh。这种方式我可以根据需要进行监控,但现在程序的输出是在一个文件中,而不是在python中,因此我必须让python读取一个大的日志文件,并在需要时捕获错误消息,因此我更愿意避免类似的情况。而不是使用
子流程。检查输出,您可以使用。此对象表示您的子流程,并具有可以读取的stdout和stderr属性。如果您的子流程只使用标准输出,您可能只需在循环中调用Popen.stdout.readline()
。但是,如果子流程写入其他管道,则可能会出现死锁(有关详细信息,请参阅文档)。在这种情况下,我建议使用中介绍的consume
函数,它可以安全地在子流程输出时逐行打印stdout和stderr
或者,如果将shell=True
传递给check\u输出
函数,则使用subprocess.check\u输出(['program','>','logfile'])的方法应该可以工作。
是一个shell指令,如果将其作为独立命令运行,则无法识别该指令
编辑:以上内容不会返回任何可供Python程序使用的输出。相反,子流程。检查输出('program | tee logfile',shell=True)
如果使用shell=True,请注意您完全可以控制检查\u输出的参数。为了安全起见,决不允许将任何用户或网络输入传递到shell。请参阅以了解原因。以澄清:shell重定向和管道直接由Unix shell处理(就底层系统调用而言:open()、dup()、pipe()等等)。这一切都是在调用execve()之前由子shell完成的。如果可能,Python subprocess.Popen()将直接调用execv(),但如果shell=True,则将创建一个shell并传递一个用于解析的命令。前一种(默认)方法更安全,因为shell命令解析有许多功能,可以以微妙甚至模糊的方式加以利用。您似乎对result=subprocess的看法是正确的。如果使用shell=true,请检查输出(['program','>','logfile']);但是,如果必须读取输出文件,则会导致问题如果我这样做,“结果”似乎是空的。如果我使用Popen(我在变通bash脚本中使用了Popen),也会发生同样的情况。我希望我的程序的输出同时通过管道传输到一个文件和一个python字符串。也许那是不可能的,谁知道呢。对我来说,以后让python读取日志文件可能更好…@iammax您可以使用tee
将输出传输到文件,同时仍将其发送到stdout。i、 e.program | tee logfile
将把program
的输出写入stdout和文件。该答案的一个问题是:如果我这样做:result=subprocess。检查输出('program | tee logfile',shell=True),程序在终端中被终止(通过使用pkill程序,如果我在日志文件中看到它在循环中,我必须杀死它),它应该返回失败代码。但是它没有,检查输出不会进入异常。它将程序的不完整输出放入“结果”中,然后使我的另一个解析结果的函数崩溃。但是,如果我关闭| tee日志文件部分,它确实会像预期的那样报告失败。这是因为程序的行为还是tee?添加到前面的注释:如果我简单地使用>将其传输到文件,而不是使用tee,它也会“正确失败”