我有一个名为 my_own_exe
的交互式程序。首先,它打印出 alive
,然后你输入 S\n
,然后它再次打印出 alive
。最后输入 L\n
。它进行一些处理并退出。
但是,当我从以下 python 脚本调用它时,程序似乎在打印出第一个“活着”后挂起。
这里有人能告诉我为什么会这样吗?
//看完后续(谢谢大家),修改代码如下:
import subprocess
import time
base_command = "./AO_FelixStrategy_UnitTest --bats 31441 --chix 12467 --enxutp 31884 --turq 26372 --symbol SOGN --target_date " + '2009-Oct-16'
print base_command
proc2 = subprocess.Popen(base_command, shell=True , stdin=subprocess.PIPE,)
time.sleep(2);
print "aliv"
proc2.communicate('S\n')
print "alive"
time.sleep(6)
print "alive"
print proc2.communicate('L\n')
time.sleep(6)
程序现在可以很好地处理第一个输入“S\n”,但随后停止,第二个“L\n”有点被忽略了。
谁能告诉我为什么会这样?
最佳答案
Interact with process: Send data to stdin. Read data from stdout and stderr, until end-of-file is reached. Wait for process to terminate.
所以在 communicate()
运行后,进程已经终止。
如果你想在不等待进程停止的情况下写入和读取:
永远不要使用
shell=True
- 它不必要地调用一个shell来调用你的程序,所以你和你之间会有另一个进程你的程序。这有很多不愉快的副作用。默认值是shell=False
所以你应该坚持使用它。 将Popen
行更改为:p = subprocess.Popen(["./AO_FelixStrategy_UnitTest", "--bats", "31441", "--chix", "12467", "--enxutp", "31884", "--turq", "26372", "--symbol", "SOGN", "--target_date", '2009-Oct-16'], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
使用
p.stdin.write
写入进程。使用p.stdout.read
从中读取。- 如果没有可读取的内容,则调用
p.stdout.read
将阻塞。如果写入缓冲区已满,调用p.stdin.write
将阻塞。所以你必须确保你有一些东西可以读/写——你在 unix 操作系统上使用select
来做到这一点。不幸的是,在 Windows 上你必须求助于线程。至少那是Popen.communicate
在内部所做的事情。 - 如果您没有编写
AO_FelixStrategy_UnitTest
那么您可能会遇到其他问题:- 它可能是从其他地方读取的,而不是标准输入。一些程序直接从终端读取,另一些程序使用一些 OS API 来读取。这意味着写入标准输入的数据不会进入程序。这通常适用于密码提示。
- 请记住,您必须考虑
AO_FelixStrategy_UnitTest
缓冲区。默认情况下,标准 C PIPE 通信被缓冲,因此在关闭输入端之前您可能看不到任何输出(通过执行p.stdin.close()
。除非AO_FelixStrategy_UnitTest
定期刷新输出。
根据您的描述,这是一些示例代码。它的工作取决于 AO_FelixStrategy_UnitTest
的开发方式:
p = subprocess.Popen(["./AO_FelixStrategy_UnitTest",
"--bats", "31441", "--chix", "12467",
"--enxutp", "31884", "--turq", "26372",
"--symbol", "SOGN", "--target_date", '2009-Oct-16'],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE)
output = p.communicate('S\nL\n')[0]
print output
关于python - 为什么 python.subprocess 在 proc.communicate() 之后挂起?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2408650/