我有以下大量的Python代码(运行v2.7)导致在MemoryError处理大(几GB)文件时抛出异常:
myProcess = Popen(myCmd, shell=True, stdout=PIPE, stderr=PIPE)
myStdout, myStderr = myProcess.communicate()
sys.stdout.write(myStdout)
if myStderr:
sys.stderr.write(myStderr)
Run Code Online (Sandbox Code Playgroud)
在阅读文档时Popen.communicate(),似乎有一些缓冲:
注意读取的数据缓冲在内存中,因此如果数据大小很大或不受限制,请不要使用此方法.
有没有办法禁用此缓冲,或强制缓存在进程运行时定期清除?
我应该在Python中使用什么替代方法来运行将千兆字节数据流式传输到的命令stdout?
我应该注意,我需要处理输出和错误流.
我正在尝试使用该subprocess模块与Python的命令行聊天机器人进行通信.(http://howie.sourceforge.net/使用编译的win32二进制文件,我有我的理由!)
这有效:
proc = Popen('Howie/howie.exe', stdout=PIPE,stderr=STDOUT,stdin=PIPE)
output = proc.communicate()
Run Code Online (Sandbox Code Playgroud)
但是Popen.communicate等待进程终止(并将其发送给EOF?),我希望能够与它进行交互.对此的明显解决方案是如此读stdout/写stdin:
这不起作用:
proc = Popen('Howie/howie.exe', stdout=PIPE,stderr=STDOUT,stdin=PIPE)
while True: print proc.stdout.readline()
Run Code Online (Sandbox Code Playgroud)
(请注意,我实际上使用的是基于http://code.activestate.com/recipes/440554/的更复杂的代码,但问题是相同的.)
问题是,第二种方法非常适合与cmd进行通信,但是当我运行聊天机器人时,什么都没有.所以我的问题是,在使用Popen.communicate()捕获输出时有什么不同?
即我可以使用第二种方法按照正常情况使用命令行,直到我运行chatbot,此时我停止接收输出.使用第一种方法正确显示机器人的前几行输出,但让我无法与它进行交互.
我正在尝试使用python自动化进程.如果我只是在终端,工作流程如下:
user:> . /path/to/env1.sh
user:> python something.py
user:> exit
user:> . /path/to/env2.sh
user:> python something2.py
user:> exit
Run Code Online (Sandbox Code Playgroud)
等几步.每个都会env.sh生成一个新脚本,其中包含大量环境变量以及当前目录中未设置的内容.我很确定我需要使用子进程,但我不确定如何去做.理想情况下,工作流程将是:打开新shell - >运行一些命令 - >退出shell - >根据需要重复.
编辑:似乎需要一些澄清.我理解如何使用subprocess.Popen()和subprocess.call()从调用Python脚本的shell中调用东西.这不是我需要的.当一个人调用env.sh它时,它会设置大量的环境变量和一些其他相关的东西,然后将你放入一个shell来运行命令.重要的是要注意在运行所需命令后env.sh直到一种类型exit才会终止.使用subprocess.call("./env.sh", shell = True)打开shell并停在那里.这就像输入命令一样,./env.sh除了发出exit命令时,其余的python脚本.所以:
subprocess.call(". /path/to/env.sh", shell = True)
subprocess.call("python something.py", shell = True)
Run Code Online (Sandbox Code Playgroud)
不做我需要做的事情,也不做:
p = subprocess.Popen(". /path/to/env.sh", shell = True)
subprocess.call("python something.py", shell = True)
p.kill()
Run Code Online (Sandbox Code Playgroud)