Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/364.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子流程的实时管道。检查\u输出或解决方案?_Python_Subprocess_Pipe - Fatal编程技术网

带python子流程的实时管道。检查\u输出或解决方案?

带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

我的一个大型项目的一部分包括一个python部分,如下所示:

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,它也会“正确失败”