【发布时间】:2020-02-08 10:09:43
【问题描述】:
我正在尝试创建一个与 /bin/bash shell 交互并获取信息或执行命令的进程。我不想关闭进程,因为我想保留状态以供将来交互。
我在SO answer 上尝试了解决方案,但在一次通信后进程终止。
通过pythonsubprocess API,我发现subprocess.check_output() 非常适合这个。但是,类似于Popen.communicate(),这会在执行一次后终止进程。
最后一种似乎可行但不安全并导致死锁的方法是使用Popen.stdin.write 和Popen.stdout.read。如果未找到 EOF,则读取操作将进入无限等待。
有没有更安全、更简单的方法来实现这一点?
编辑: 我尝试了更多的东西:
import subprocess
import select
import os
process = subprocess.Popen(['/bin/bash'], shell=True, text=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
process.stdin.write('export SOMETHING=10000abc\n')
process.stdin.flush()
process.stdin.write('echo $SOMETHING\n')
process.stdin.flush()
r, w, e = select.select([process.stdout], [process.stdin], [], 0)
if process.stdout in r:
print (os.read(process.stdout.fileno(), 50))
else:
print ("Nothing to read")
输出总是Nothing to read
【问题讨论】:
-
你应该使用
pexpect。 -
使用
readline而不是read。 -
readline() 面临与 read() 相同的问题,它可能导致死锁。到目前为止,我正在考虑在读取操作上添加超时以打破死锁。
-
问题可能是由于标准输出是管道时 stdio 缓冲造成的。这就是您应该使用
pexpect的原因,它通过使用pty 来解决这个问题。
标签: python bash process subprocess popen