Python子进程非阻塞并返回输出

0 投票
2 回答
2437 浏览
提问于 2025-04-17 08:15

我知道这个问题被问过很多次,但我还是没找到一个合适的方法。如果我想运行一个本地命令,文档上说我必须使用subprocess,因为它取代了其他方法,比如os.system和popen等。

如果我在程序中调用 subprocess.Popen(command, shell=True, stdout=subprocess.PIPE),假设这个命令是一个openvpn指令,用来把我的电脑连接到VPN,那么这个过程会一直挂着,因为openvpn的输出会以换行符结束,但在连接时它会一直保持挂起,这样我的程序也就“冻住”了。

有人说我应该去掉 stdout=subprocess.PIPE,这样确实可以让程序不再挂起,但所有的输出都会直接打印到控制台,这样我就无法控制输出(也许我不想打印它)。

那么有没有什么合适的方法可以做到这一点呢?比如说,有没有例子可以展示如何以非阻塞的方式执行命令,同时又能控制输出?

2 个回答

-1

考虑在终端中运行你的程序。例如,

subprocess.Popen("xterm -e /bin/bash -c '/path/to/openvpn'", shell=True)

或者,你也可以试试,

import shlex
subprocess.Poen(shlex.split("xterm -e /bin/bash -c '/path/to/openvpn'"), shell=False)
0

如果你设置了stdout=PIPE,那么你的子进程会把输出写入一个管道里,当这个管道满了的时候,子进程就会卡住。你的Python程序不应该卡住,因为Popen是异步的,这就是为什么可以在之后调用Popen.wait()来等待子进程结束。为了让子进程保持正常运行,你需要从Popen.stdout中读取数据,然后根据需要打印、丢弃或者处理这些输出。

撰写回答