java - subprocess.Popen 的奇怪执行模式

标签 java python 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)

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

上面的工作,但是,我没有从 JAR 进程中获得任何日志记录。我试过这样调用它:

proc = subprocess.call(jar_command)

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

为什么忽略后续 shell 脚本?

最佳答案

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

您可以通过在 bash 脚本中添加虚拟文件创建来验证这一点。把它放在脚本的第一行,所以如果它被执行,你会得到创建的虚拟文件。如果它没有被创建,这意味着脚本没有被执行,可能是由于 java 执行的原因。

我会尝试一些事情:

首先,我将返回 Popen 而不是 call。不使用 wait(),而是使用 communicate():

Interact with process: Send data to stdin. Read data from stdout and stderr, until end-of-file is reached. Wait for process to terminate. communicate() returns a tuple (stdoutdata, stderrdata).

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

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

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

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

proc = subprocess.check_call(jar_command)

Run command with arguments. Wait for command to complete. If the return code was zero then return, otherwise raise CalledProcessError.

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

关于java - subprocess.Popen 的奇怪执行模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46647608/

相关文章:

Linux、BASH 带有特殊字符的启动命令

java - FindBugs 找不到 org.apache.bcel.classfile.ClassFormatException

java - 带有 achartengine 适配代码的电池图表

java - tomcat处理错误页面时没有语言环境?

python - Poplib 无法正常工作?

python - 参数必须是字节或unicode,得到 '_Element'

JVM 关闭时 Java 子进程死亡

java - socket.accept() 不执行

python - 使用列表理解创建列表列表

bash - linux bash,命令 'gnome-terminal",转义引号