关于Python中pexpect的问题
我尝试使用 Python 的 pexpect 和 subprocess.Popen 来调用一个外部的长期后台进程(这个进程通过 socket 和外部应用程序进行通信),以下是一些细节。
subprocess.Popen(launchcmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 这个方法很好用。我不需要做其他的事情。不过,因为我需要立即获取输出,所以我选择了 pexpect,以避免管道文件的缓冲问题。
obj = pexpect.spawn(launchcmd, timeout=None) 在启动外部进程后,我使用一个单独的线程来执行 "readline",读取启动进程 "obj" 的输出,一切都正常。
obj = pexpect.spawn(launchcmd, timeout=None) 在启动外部进程后,我没有做进一步的操作,也就是就让它在那里待着。虽然我可以通过 "ps -e" 命令找到这个启动的进程,但这个进程似乎被阻塞了,无法通过 socket 和其他应用程序进行通信。
好的,为了更具体一点,我放了一些示例代码来说明我的问题。
import subprocess
import pexpect
import os
t=1
while(True):
if(t==1):
background_process="./XXX.out"
launchcmd = [background_process]
#---option 3--------
p=pexpect.spawn(launchcmd, timeout=None) # process launced, problem with socket.
#---option 1--------
p=subprocess.Popen(launchcmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) # process launced, everything fine
t=0
有没有人能告诉我第三个选项有什么问题?如果是因为我没有使用单独的线程来处理输出,那为什么第一个选项在使用 subprocess.popen 时能正常工作?我怀疑 pexpect 在使用 socket 启动进程时可能有问题,但我不太确定,尤其是考虑到第二个选项运行得很好。
1 个回答
我觉得你把事情搞得太复杂了。
没错,使用pty
来和后台进程沟通确实是个好主意,因为大多数应用程序都能识别tty/pty设备,并且会切换到使用无缓冲输出(或者至少是行缓冲输出)。
但是为什么要用pexpect呢?直接用Python的pty模块就行了。首先调用openpty
来获取一些文件句柄,然后用Popen
来启动进程。示例代码可以在下面这个问题中找到(带绿色勾的答案) Python运行一个守护子进程并读取标准输出