[英]Output of proc.communicate() does not format newlines in django python
[英]why does python.subprocess hang after proc.communicate()?
我有一个名为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' 有点被忽略。
谁能告诉我为什么会这样?
与进程交互:将数据发送到标准输入。 从 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
将阻塞。 所以你必须确保你有一些东西可以读/写 - 你可以在 unix OS 上使用select
做到这一点。 不幸的是,在 Windows 上,您必须求助于线程。 至少这是Popen.communicate
在内部所做的。AO_FelixStrategy_UnitTest
那么您可能会遇到其他问题:
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
communicate()
从标准输出和标准错误读取数据,直到到达文件结尾。 - 它一直等到你的程序退出。
comunicate只会运行一次,然后会关闭管道,因此如果您想向它发送多个命令,您需要在同一个字符串中一个接一个地发送。
这是经过一些调查后对我有用的示例,尝试了线程、subprocess32、stdin.write、stdout.read 等。此信息不在用于通信的官方 python 参考信息中: https ://docs.python.org/ 2/library/subprocess.html
我发现这一点的唯一地方是在这里: Python subprocess communication 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) 以及中间的 a 参数(交互式地提醒您),您可以这样称呼它:
cmd_parms = "\n\n\n\n\nparm\n\n"
errcode, out, err = do_commands(command, cmd_parms)
希望能帮助到你。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.