Python: subprocess.Popen 和 subprocess.call 挂起

17 投票
2 回答
20974 浏览
提问于 2025-04-17 06:02

我在使用subprocess.Popen或subprocess.call的时候遇到一个问题。当我用它们来执行一些输出很多的命令时,Python脚本就会卡住。不过奇怪的是,等了一段时间后,虽然脚本还在卡着,但我发现命令行执行的任务其实已经完成了,只有脚本本身还在挂着。

subprocess.call(cmd, shell = True)
#OR
subprocess.Popen(cmd, stdout = subprocess.PIPE, stdin = subprocess.PIPE, shell = True)
# HANGS HERE
print "show something after subprocess"

注意,最后的打印语句从来没有执行,但实际上命令已经执行完了。

还有一点要注意,这个命令和串口有关,所以当我拔掉串口线的时候,一切就正常了,最后的打印语句也能执行。但是当我在终端使用这个命令时,即使串口线插着也没问题,只有在Python脚本中会出现这个问题。

非常感谢!

2 个回答

1

我不明白你第一行代码为什么不工作——因为没有输入输出的重定向,所以不需要阻塞。

第二行代码应该会阻塞,情况是:

  1. 如果进程需要通过输入流(stdin)接收数据,或者
  2. 如果它发送到输出流(stdout)的数据超过了管道能承受的量,而这些数据又没有被读取。

但是因为你的子进程正常结束,我看不出为什么会阻塞。你确定它真的结束了吗?

18

根据Python的文档,subprocess.call这个函数会运行一个命令,并且会等这个命令执行完毕,所以它的作用相当于先用subprocess.Popen启动命令,然后再用Popen.wait来等待。

不过,Popen.wait这个方法的文档特别提醒了一个问题,就是缓冲区溢出的问题,因此建议使用Popen.communicate来代替。所以,你要找的解决方案应该是类似这样的:

import subprocess
process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stdin=subprocess.PIPE, shell=True)
stdout, stderr = process.communicate()
print "show something after subprocess"

撰写回答