我有一个名为my_own_exe
的互动程序。首先,它打印出alive
,然后输入S\n
,然后再打印出alive
。最后输入L\n
。它做了一些处理和退出。
然而,当我从下面的python脚本中调用它时,程序似乎在打印出第一个'alive'后挂起。
这里有人能告诉我为什么会这样吗?
//阅读后续内容(谢谢你们),我修改了以下代码:
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'有点被忽略了。
有谁能让我知道为什么会这样?
答案 0 :(得分:27)
与流程交互:将数据发送到stdin。从stdout和stderr读取数据,直到达到文件结尾。 等待进程终止。
因此,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
将阻止。因此,您必须确保有一些可读/写的内容 - 您可以使用select
在unix OS上执行此操作。在Windows上,你不幸的是必须求助于线程。至少这是内部Popen.communicate
的作用。AO_FelixStrategy_UnitTest
,那么您可能会遇到其他问题:
AO_FelixStrategy_UnitTest
缓冲区。默认情况下,标准C PIPE通信是缓冲的,因此在您关闭输入端之前可能看不到任何输出(通过执行p.stdin.close()
。除非AO_FelixStrategy_UnitTest
定期刷新输出。这是一些示例代码,基于您描述的内容。根据{{1}}的开发方式,它可以发挥作用:
AO_FelixStrategy_UnitTest
答案 1 :(得分:4)
communicate()
从stdout和stderr 读取数据,直到到达文件结尾。 - 等待你的程序退出。
答案 2 :(得分:1)
通信 只运行一次 ,然后关闭管道,因此如果要向其发送多个命令,则需要在< strong> 相同字符串 。
这是一个在经过一些调查后尝试使用的示例,尝试了thread,subprocess32,stdin.write,stdout.read等等。这些信息不在官方python参考信息中进行通信:https://docs.python.org/2/library/subprocess.html
我发现这一点的唯一地方是: Python subprocess communicate kills my process
无论如何这里是代码,简单,没有线程,没有subprocess32,适用于linux和windows。是的,您必须知道向其他进程发送命令的次数,但一般情况下您确实知道这一点。除此之外,您可以添加线程,cwd,shell = True或您可能想要的任何其他内容,但这是最简单的情况:
def do_commands(self, cmd, parms):
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE )
# wait for the process to terminate
out, err = process.communicate(cmd_parms)
errcode = process.returncode
return errcode, out, err
因此,例如,如果您要向正在调用的应用程序发送多个回车符(\ n),并在中间发送一个参数(交互式地提醒您),您可以将其称为:
cmd_parms = "\n\n\n\n\nparm\n\n"
errcode, out, err = do_commands(command, cmd_parms)