2014-10-29 109 views
0

外部二进制输出从我的Python脚本我需要调用因此两个外部二进制文件,以处理文件中的两个步骤:处理文件输入/从蟒蛇

import os, subprocess 
sbp = subprocess.Popen(['program_1', '-i', 'input.file', '-o', 'temp.file']) 
sbp = subprocess.Popen(['program_2', '-i', 'temp.file', '-o', 'output.file'])      
os.remove('temp.file') 

不过,这将是不错的速度 - 通过使用基于虚拟RAM的文件而不是基于“物理”磁盘的管道来减少磁盘使用量。我知道我可以使用StringIOtempfile.SpooledTemporaryFile()来处理Python脚本中的虚拟文件,但有没有可能将链接传递给这样的文件到外部二进制文件?

回答

0
from subprocess import Popen 
from tempfile import NamedTemporaryFile 

tmp = NamedTemporaryFile('w+') 
sbp = Popen(['program_1', '-i', 'input.file', '-o', tmp.name]) 
sbp = Popen(['program_2', '-i', tmp.name, '-o', 'output.file'])      
tmp.close() 

最后tmp将被删除。

+0

它也没有找到临时文件到RAM – Roman 2014-10-29 13:38:11

+0

您正在寻找的是[mmap](https://docs.python.org/2/library/mmap.html)模块 – 2014-10-29 16:02:18

+0

当您调用外部二进制,它不能与标准输入/标准输出一起使用,你必须提供包含'-i'/' - o'键的文件路径的字符串变量。在tempfile模块中有一个特殊的属性'name'。但是,mmap似乎没有模拟。可能,这根本不可能。 – Roman 2014-10-29 16:28:01

1

假设你可以告诉你2个程序读取,并从标准输入和stdout写入/,你可以管从一个子命令其他:

import os, subprocess 
sp1 = subprocess.Popen(['program_1', '-i', 'input.file'], stdout=subprocess.PIPE) 
sp2 = subprocess.Popen(['program_2', '-o', 'output.file'], stdin=sp1.stdout) 
sp1.stdout.close() 
sp2.communicate() 

https://docs.python.org/2/library/subprocess.html#replacing-shell-pipeline

另一个选项(UNIX)是使用命名管道(在操作系统级别创建的,例如mkfifo /tmp/mypipe):

import os, subprocess 
os.mkfifo('/tmp/mypipe') 
sp1 = subprocess.Popen(['program_1', '-i', 'input.file', '-o', '/tmp/mypipe']) 
sp2 = subprocess.Popen(['program_2', '-i', '/tmp/mypipe', '-o', 'output.file']) 

而且它也应该可以使用os.pipe()

+0

这就是程序无法读写标准输入/输出的问题。第二个选项似乎也使用HDD,所以它只是一种将临时文件放在另一个地方的方法,而不是绕过它的创建。 – Roman 2014-10-29 13:35:23

+0

命名管道/ fifo并不是真正的文件,因为它不会将用户数据写入磁盘。至少在Linux中,内核将在读写过程之间转发数据而不写入文件系统。另外,在适当的情况下,读写过程将在IO上阻塞。除非读者已经在非阻塞模式下打开管道,否则读取器将会阻塞,如果没有什么可读的话。鉴于目标程序与stdin/stdout的不灵活性,命名管道可能是最好的解决方案。 – mhawke 2014-10-30 10:47:28

+0

是否有可能同时使用多个管道?我的脚本是多线程的,所以我用这种语法等待线程之间的冲突。 – Roman 2014-10-30 12:42:25