2012-08-06 36 views
4

我读过了subprocess.Popen上的所有内容,但我想我错过了一些东西。将数据从python传输到外部命令

我需要能够执行一个unix程序,它从python脚本中创建的列表读取数据流,并将该程序的结果写入文件。从bash提示符开始,我始终没有问题,但现在我正试图从一个python脚本内预处理一些二进制文件和大量数据,然后进入这个阶段。

让我们看看一个简单的例子不包括所有的预处理:

import sys 
from pylab import * 
from subprocess import * 
from shlex import split 

# some arbitrary x,y points 
points = [(11,31),(13,33),(15,37),(16,35),(17,38),(18,39.55)] 

commandline = 'my_unix_prog option1 option2 .... > outfile' 
command = split(commandline) 

process = Popen(command, stdin=PIPE, stdout=PIPE, stderr=PIPE) 
print process.communicate(str(points)) 

这将在bash被执行的方式是:

echo "11 31 
     13 33 
     15 37 
     16 35 
     17 38 
     18 39.55" | my_unix_prog option1 option2 .... > outfile 

的方式中的数据被馈送到UNIX PROG也很重要,我应该格式化为2列,用空格分隔。

任何帮助表示赞赏...

+0

在'command'中,您将输出重定向到'outfile',但是您尝试使用'communic'将其读入到您的程序中。你想在哪里输出? – 2012-08-06 14:16:07

+1

使用'>'不是将输出重定向到文件的方式,请参阅此答案:http://stackoverflow.com/questions/8902206/subprocess-popen-io-redirect – Dhara 2012-08-06 14:20:06

回答

3

解决了!

随着Dharaxhainingx帮助,我能想出解决办法:

import sys 
from pylab import * 
from subprocess import * 
from shlex import split 

# some arbitrary x,y points 
points = [(11,31),(13,33),(15,37),(16,35),(17,38),(18,39.55)] 

commandline = 'my_unix_prog option1 option2 ....' 
command = split(commandline) 

process = Popen(command, stdin=PIPE, stdout=open('outfile', 'w'), stderr=PIPE) 
for p in points: 
    process.stdin.write(str(p[0]) + ' ' + str(p[1]) + '\n') 

print process.communicate() 

这个作品非常好,谢谢。

+0

我还建议您在调用Popen之外创建文件对象,以便稍后在您和您的子进程通过时调用'.close()' – 2012-08-06 18:31:17

1

怎么像

for p in points: 
    process.stdin.write(str(p[0]) + ' ' + str(p[1]) + '\n') 

print process.communicate() 
+0

是的,你是对的(两者都是你),但我认为我的问题在此之前开始:我使用'>'重定向,但这是外壳重定向,无效。 – Shahar 2012-08-06 14:35:26

+0

@Shahar你可以在你的Popen构造函数中使用'shell = True'参数来允许shell重定向,但是'communic''不会返回任何标准输出。另一个选择是打开一个文件'f = open('outfile','w')',然后用'stdout = f'来代替'PIPE'。我不确定现在有什么问题 – 2012-08-06 15:16:58

0

您需要格式化您的输入正确沟通。

str当你打印你不想要的元组列表时,将保留特殊字符。

>>> print str([(1,2), (3,4)]) 
[(1,2), (3,4)] 

试试这个:

print process.communicate("\n".join(["%s %s"%(x[0], x[1]) for x in points])