subprocess.Popen的奇怪执行模式

Nan*_*nor 5 python java bash shell

我有一个Python脚本,其中调用了JAR.调用JAR后,将调用两个shell脚本.最初我这样做:

proc = subprocess.Popen(jar_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
proc.wait()
output, errors = proc.communicate()

proc = subprocess.Popen(prune_command, shell=True)
proc.wait()

proc = subprocess.call(push_command, shell=True)
Run Code Online (Sandbox Code Playgroud)

我必须等待前两个进程完成所以我使用Popen()和最后一个我可以让它在后台运行,所以我call().我通过,shell=True因为我希望被调用的shell脚本可以访问环境变量.

但是,上面的工作,我没有从JAR进程中获取任何日志记录.我试过这样称呼它:

proc = subprocess.call(jar_command)
Run Code Online (Sandbox Code Playgroud)

这是我所期望的日志,但后面的两个shell脚本不会被执行.最初我认为日志不会发生,stdout但事实证明它们根本没有被执行.IE不删除多余的文件或推送到数据库.

为什么后续shell脚本被忽略?

Che*_* A. 3

如果您确定您的 shell 脚本根本没有运行,并且第一个代码一切正常 - 那么它一定是java 命令死锁或没有使用该call()函数正确终止。

您可以通过在 bash 脚本中添加虚拟文件创建来验证这一点。将其放在脚本的第一行,因此如果执行它,您将创建创建的虚拟文件。如果未创建,则意味着脚本未执行,可能是由于 java 执行的原因所致。

我会尝试几件事:

首先我会返回Popen而不是call. 不要使用wait(),而是使用communicate()

与进程交互:将数据发送到标准输入。从 stdout 和 stderr 读取数据,直到到达文件末尾。等待进程终止Communication()返回一个元组(stdoutdata, stderrdata)

proc = subprocess.Popen(jar_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
proc.communicate()
Run Code Online (Sandbox Code Playgroud)

确保检查两个流的数据(stdout 和 stderr)。您可能会错过 java 进程引发的错误。

bufsize=0接下来,我将尝试通过提供to来禁用缓冲区Popen。它将消除与 python 缓冲相关的选项。

如果这两个选项仍然不起作用,请尝试使用以下命令查看是否存在异常check_call()

proc = subprocess.check_call(jar_command)
Run Code Online (Sandbox Code Playgroud)

运行带参数的命令。等待命令完成。如果返回代码为零则返回,否则引发 CalledProcessError

这些选项可能有答案;如果没有,他们将帮助调试过程。请随意评论这一进展如何。