Python Popen.subprocess退出状态为0,但程序在子流程成功完成后立即退出

Python Popen.subprocess退出状态为0,但程序在子流程成功完成后立即退出,python,subprocess,Python,Subprocess,我试图实时查看子流程的实时输出。我在这里试过几种方法,但都不管用。现在我有了一个有效的方法,但它会导致我的程序在成功完成子流程后立即退出。我得到的返回码是零。该命令在FreeBSD监狱(如chroot)中运行,并且实际上有效,它只是在完成程序的其余部分之前退出 import os, sys, subprocess DEVNULL = open(os.devnull, 'w') save = DEVNULL tick = re.escape("'") Jcmd = "jexec 1

我试图实时查看子流程的实时输出。我在这里试过几种方法,但都不管用。现在我有了一个有效的方法,但它会导致我的程序在成功完成子流程后立即退出。我得到的返回码是零。该命令在FreeBSD监狱(如chroot)中运行,并且实际上有效,它只是在完成程序的其余部分之前退出

 import os, sys, subprocess

 DEVNULL = open(os.devnull, 'w')
 save = DEVNULL

 tick = re.escape("'")
 Jcmd = "jexec 1 sh -c '/usr/local/bin/aria2c --quiet=false -x 10 " + re.escape(links[1]) + tick
 proc = subprocess.Popen(Jcmd, shell=True)
 returncode = proc.wait()
 print "RETURN CODE: ", returncode
 sys.stdout = save
 print "THIS PRINT STATEMENT DOES NOT EXECUTE, PYTHON EXITS BEFORE"


OUTPUT:

Download Results:
gid   |stat|avg speed  |path/URI
======+====+===========+=======================================================
c28be0|OK  |       0B/s|/usr/local/MOUNTPOINTS/_DOWNLOADS/document.pdf

Status Legend:
(OK):download completed.
RETURN CODE:  0

我认为您的意思是在执行另一个进程时使stdout静音,以防止python输出弄乱子进程的输出。然而,这在这里可能是不必要的,因为您的python代码只是等待,所以它无法打印任何内容

如果要使python打印静音,然后恢复它们,则更像这样:

import os, sys
with open(os.devnull, 'w') as DEVNULL:
    save = sys.stdout # this is what you want to restore later
    sys.stdout = DEVNULL
    print "this prints to devnull (not really)"
    sys.stdout = save # restore the original sys.stdout

print "this prints to stdout"

请注意,save只是实际sys.stdout的一个临时变量,您希望稍后返回。

正如@Kenny所指出的,我已经重定向了sys.stdout,而我的程序在sys.stdout=save之后实际上仍在做一些事情。我在那之后添加了这一行以将输出恢复到屏幕,sys.stdout=sys。stdout。因此,这一切都是:

import os, sys, subprocess

 # Next 2 lines not needed
 # DEVNULL = open(os.devnull, 'w')
 # save = DEVNULL

 tick = re.escape("'")
 Jcmd = "jexec 1 sh -c '/usr/local/bin/aria2c --quiet=false -x 10 " + re.escape(links[1]) + tick
 proc = subprocess.Popen(Jcmd, shell=True)
 returncode = proc.wait()
 print "RETURN CODE: ", returncode

 # Next 2 lines not needed
 #sys.stdout = save
 #sys.stdout = sys.__stdout__

 print "THIS PRINT STATEMENT DOES NOT EXECUTE, PYTHON EXITS BEFORE"

您忘记导入操作系统、系统和子流程。如果我解决了这个问题,并将命令行更改为“ls”或“dir”,这对我来说是有效的。它退出,因为它已到达程序的末尾。如果我在它后面添加更多代码,它就会执行(除了print,print会执行,但显然不会执行任何操作,因为devnull)@Kenny,我没有忘记导入操作系统等等,我只是没有将它们包含在我的示例中。在这之后,我还有很多其他代码,包括在sys.stdout=save行之后的一个打印,它不打印,Python在此之前退出。另外,“ls”不是一个好的测试,因为我显示的输出是下载进度,而且非常冗长。不管怎么说,问题在于它完成后没有发生什么。为什么要使用
tick=re.escape(“”)
?这将创建字符串
“\\'”
,这可能是正确的,原因我想不起来,但它似乎不会关闭
”/usr/local/…
中的开口
。感谢修复此问题。看起来第二个print语句确实执行了,但是它没有可见的输出,因为您告诉它打印到操作系统。devnull@eryksun我同意,但经过多次尝试,这就是最终对我起作用的原因。否则,re.escape(links[1])不会展开。基本上我有3个嵌套命令。一切都正常,只是在它回来后继续。我并不是真的想让任何东西安静下来。我尝试过的其他方法都是等到子流程完成后再输出最终结果。我需要实时输出,我使用的方法按照我预期的方式工作,至少在子流程完成之前是这样。现在一切都按照我预期的方式进行。谢谢但在这段代码中,从未使用save和DEVNULL。保存变量的目的是在将sys.stdout的原始值更改为devnull时保持其安全。然后你以后再恢复它。看到我的答案了。你是对的,我在遵循我在这里找到的另一个例子。我注释掉了这些行,以及sys.stdout=save行,所有操作仍然正常。再次感谢!