2013-04-08 156 views
0

我正在尝试编写一个Python函数,它将给定的坐标系转换为使用gdal的另一个坐标系。问题是我试图以一个字符串执行该命令,但在shell中,我必须在输入坐标之前按Enter键。使用Python命令的多行shell命令模块

x = 1815421 
y = 557301 

ret = [] 

tmp = commands.getoutput('gdaltransform -s_srs \'+proj=lcc +lat_1=34.03333333333333 
+lat_2=35.46666666666667 +lat_0=33.5 +lon_0=-118 +x_0=2000000 +y_0=500000 +ellps=GRS80 
+units=m +no_defs\' -t_srs epsg:4326 \n' + str(x) + ' ' + str(y)) 

我试过用'\ n',但那不起作用。

+0

是否有任何理由不在Python中调用osr.CoordinateTransformation()? – 2013-04-09 06:30:44

回答

3

我的猜测是,你按Enter键运行gdaltransform和坐标由从标准输入程序本身读,而不是外壳:

from subprocess import Popen, PIPE 

p = Popen(['gdaltransform', '-s_srs', ('+proj=lcc ' 
    '+lat_1=34.03333333333333 ' 
    '+lat_2=35.46666666666667 ' 
    '+lat_0=33.5 ' 
    '+lon_0=-118 +x_0=2000000 +y_0=500000 +ellps=GRS80 ' 
    '+units=m +no_defs'), '-t_srs', 'epsg:4326'], 
    stdin=PIPE, stdout=PIPE, universal_newlines=True) # run the program 
output = p.communicate("%s %s\n" % (x, y))[0] # pass coordinates 
1
from subprocess import * 

c = 'command 1 && command 2 && command 3' 
# for instance: c = 'dir && cd C:\\ && dir' 

handle = Popen(c, stdin=PIPE, stderr=PIPE, stdout=PIPE, shell=True) 
print handle.stdout.read() 
handle.flush() 

如果我没有记错,该命令将被执行在“会话”,从而让你需要在命令之间任何niformation。

更准确地说,使用shell=True(从我所得到的)是如果给定一串命令而不是一个列表,它应该被使用。如果你想使用一个列表的建议是做如下:

import shlex 
c = shlex.split("program -w ith -a 'quoted argument'") 

handle = Popen(c, stdout=PIPE, stderr=PIPE, stdin=PIPE) 
print handle.stdout.read() 

再搭上输出,或者你可以用一个开放的工作流和使用handle.stdin.write()但它是一个有点棘手。

除非你只想要执行,读而不死,.communicate()是完美的,或者只是.check_output(<cmd>)

好信息n如何Popen作品都可以在这里找到(本书虽然是不同的主题):python subprocess stdin.write a string error 22 invalid argument




解决方案

无论如何,这应该工作(你必须重定向STDIN和STDOUT):

from subprocess import * 

c = 'gdaltransform -s_srs \'+proj=lcc +lat_1=34.03333333333333 +lat_2=35.46666666666667 +lat_0=33.5 +lon_0=-118 +x_0=2000000 +y_0=500000 +ellps=GRS80 +units=m +no_defs\' -t_srs epsg:4326 \n' + str(x) + ' ' + str(y) + '\n' 

handle = Popen(c, stdin=PIPE, stderr=PIPE, stdout=PIPE, shell=True) 
print handle.stdout.read() 
handle.flush()