有没有办法在 Popen 的同一个“会话”中进行多次通话?例如,我可以通过它拨打电话,然后再拨打另一个电话,而不必将命令连接成一个长字符串吗?
3 回答
当您使用 popen 时,您不是在“打电话”,而是在运行一个可执行文件并通过 stdin、stdout 和 stderr 与它交谈。如果可执行文件有某种方式来完成工作的“会话”(例如,通过从标准输入读取行),那么,是的,你可以做到。否则,您将需要执行多次。
subprocess.Popen (大部分)只是 execvp(3) 的包装器
假设您希望能够运行 shell 并向其发送多个命令(并读取它们的输出),您似乎可以执行以下操作:
from subprocess import *
p = Popen(['/bin/sh'], shell=False, stdin=PIPE, stdout=PIPE, stderr=PIPE)
之后,例如:
>>> p.stdin.write("cat /etc/motd\n")
>>> p.stdout.readline()
'Welcome to dev-linux.mongo.com.\n'
(当然,您也应该检查stderr
,否则要求Popen
将其与 合并stdout
)。上面的一个主要问题是stdin
andstdout
管道处于阻塞模式,因此很容易“卡住”,永远等待 shell 的输出。虽然我还没有尝试过,但 ActiveState 网站上有一个配方显示了如何解决这个问题。
更新:在查看了相关的问题/答案之后,看起来使用 Python 的内置select
模块来查看是否有要读取的数据可能更简单stdout
(当然,您也应该对 执行相同的操作stderr
),例如:
>>> select.select([p.stdout], [], [], 0)
([<open file '<fdopen>', mode 'rb' at 0x10341690>], [], [])
例如,我可以通过它拨打电话,然后再拨打另一个电话,而不必将命令连接成一个长字符串吗?
听起来你正在使用 shell=True。不要,除非你需要。而是使用 shell=False (默认值)并传入命令/参数列表。
有没有办法在 Popen 的同一个“会话”中进行多次通话?例如,我可以通过它拨打电话,然后再拨打另一个电话,而不必将命令连接成一个长字符串吗?
有什么理由不能只创建两个 Popen 实例并根据需要在每个实例上等待/通信?如果我理解正确的话,这是正常的做法。