在Python中调用bash命令返回错误,但在终端中有效
以下是与此相关的我的代码:在Python中调用bash命令返回错误,但在终端中有效,python,bash,Python,Bash,以下是与此相关的我的代码: def grd_commands(directory): for filename in os.listdir(directory)[1:]: print filename new_filename = '' first_letter = '' second_letter = '' bash_command = 'gmt grdinfo ' + filename + ' -I-'
def grd_commands(directory):
for filename in os.listdir(directory)[1:]:
print filename
new_filename = ''
first_letter = ''
second_letter = ''
bash_command = 'gmt grdinfo ' + filename + ' -I-'
print bash_command
coordinates = Popen(bash_command, stdout=PIPE, shell=True)
coordinates = coordinates.communicate()
latlong = re.findall(r'^\D*?([-+]?\d+)\D*?[-+]?\d+\D*?([-+]?\d+)', coordinates)
if '-' in latlong[1]:
first_letter = 'S'
else:
first_letter = 'N'
if '-' in latlong[0]:
second_letter = 'W'
else:
second_letter = 'E'
new_filename = first_letter + str(latlong[1]) + second_letter + str(latlong[0]) + '.grd'
Popen('gmt grdconvert ' + str(filename) + ' ' + new_filename, shell=True)
filename
是传递给函数的文件名。当我运行代码时,我收到以下错误:
/bin/sh: gmt: command not found
Traceback (most recent call last):
File "/Users/student/Desktop/Code/grd_commands.py", line 38, in <module>
main()
File "/Users/student/Desktop/Code/grd_commands.py", line 10, in main
grd_commands(directory)
File "/Users/student/Desktop/Code/grd_commands.py", line 23, in grd_commands
latlong = re.findall(r'^\D*?([-+]?\d+)\D*?[-+]?\d+\D*?([-+]?\d+)', coordinates).split('\n')
File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/re.py", line 177, in findall
return _compile(pattern, flags).findall(string)
TypeError: expected string or buffer
/bin/sh:gmt:未找到命令
回溯(最近一次呼叫最后一次):
文件“/Users/student/Desktop/Code/grd_commands.py”,第38行,在
main()
文件“/Users/student/Desktop/Code/grd_commands.py”,主文件第10行
grd_命令(目录)
grd_命令中的文件“/Users/student/Desktop/Code/grd_commands.py”,第23行
latlong=re.findall(r'^\D*?([-+]?\D+)\D*?[-+]?\D+\D*?([-+]?\D+),坐标)。拆分('\n')
findall中的文件“/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/re.py”,第177行
返回编译(模式、标志).findall(字符串)
TypeError:应为字符串或缓冲区
如果我打印出字符串
bash_命令
,并尝试将其输入终端,它将完全发挥作用。为什么它在被Python脚本调用时不起作用?整个命令行都被视为一个命令名。您需要使用shell=True
让shell将其作为命令行进行解析:
coordinates = Popen(bash_command, stdout=PIPE, shell=True)
或者最好将命令名及其参数存储为列表中的单独元素:
bash_command = ['gmt', 'grdinfo', filename, '-I-']
coordinates = Popen(bash_command, stdout=PIPE)
整个命令行被视为单个命令名。您需要使用
shell=True
让shell将其作为命令行进行解析:
coordinates = Popen(bash_command, stdout=PIPE, shell=True)
或者最好将命令名及其参数存储为列表中的单独元素:
bash_command = ['gmt', 'grdinfo', filename, '-I-']
coordinates = Popen(bash_command, stdout=PIPE)
Popen接受参数列表。使用shell=True时会出现警告 如果与不受信任的输入相结合,传递shell=True可能会造成安全隐患 试试这个:
from subprocess import Popen, PIPE
bash_command = 'gmt grdinfo ' + filename + ' -I-'
print(bash_command)
coordinates = Popen(bash_command.split(), stdout=PIPE)
print(coordinates.communicate()[0])
确保gmt安装在/etc/environment文件中路径指定的位置:
PATH=$PATH:/path/to/gmt
或者,在bash_命令中指定gmt的路径:
bash_command = '/path/to/gmt grdinfo ' + filename + ' -I-'
您应该能够通过以下方式找到路径:
which gmt
正如其他人所建议的那样,实际的列表将是最好的方法,而不是字符串。此外,如果文件中有空格,则必须使用“\”转义空格,以便实际访问该文件
for filename in os.listdir(directory)[1:]:
bash_command = ['gmt', 'grdinfo', filename.replace(" ", "\ "), '-I-']
Popen接受参数列表。使用shell=True时会出现警告 如果与不受信任的输入相结合,传递shell=True可能会造成安全隐患 试试这个:
from subprocess import Popen, PIPE
bash_command = 'gmt grdinfo ' + filename + ' -I-'
print(bash_command)
coordinates = Popen(bash_command.split(), stdout=PIPE)
print(coordinates.communicate()[0])
确保gmt安装在/etc/environment文件中路径指定的位置:
PATH=$PATH:/path/to/gmt
或者,在bash_命令中指定gmt的路径:
bash_command = '/path/to/gmt grdinfo ' + filename + ' -I-'
您应该能够通过以下方式找到路径:
which gmt
正如其他人所建议的那样,实际的列表将是最好的方法,而不是字符串。此外,如果文件中有空格,则必须使用“\”转义空格,以便实际访问该文件
for filename in os.listdir(directory)[1:]:
bash_command = ['gmt', 'grdinfo', filename.replace(" ", "\ "), '-I-']
谢谢你的回答。发布问题后,我很快意识到我需要将shell=True添加到参数中,并更新了问题以处理在发布问题后遇到的实际错误。不过,我仍然强烈建议使用list参数。(我稍后会删除这个答案。)谢谢你的回答。发布问题后,我很快意识到我需要将shell=True添加到参数中,并更新了问题以处理在发布问题后遇到的实际错误。不过,我仍然强烈建议使用list参数。(我稍后会删除这个答案。)很可能这是一个路径问题;在哪个目录中找到了
gmt
?如果将单个字符串传递给Popen
,它将在Unix和Windows上执行不同的操作,并在命令提示符下键入该字符串。您应该向命令传递一个包含第一个元素路径名的列表。在Bash提示符下,您也可能有不同于Python vs的路径。在列表的第一个元素中添加gmt的路径。您正在运行sh
,而不是bash
-/bin/sh:gmt:command not found
表明gmt
所在的目录不是PATH
环境变量的一部分。请尝试给出gmt
程序的完整路径名。@cdarke我给它的是gmt的完整路径。我想可能是我没有正确存储输出。下面是命令输出在shell打印坐标中的内容。这是一个stdout和stderr的元组。您需要坐标[0]。这很可能是路径问题;在哪个目录中找到了gmt
?如果将单个字符串传递给Popen
,它将在Unix和Windows上执行不同的操作,并在命令提示符下键入该字符串。您应该向命令传递一个包含第一个元素路径名的列表。在Bash提示符下,您也可能有不同于Python vs的路径。在列表的第一个元素中添加gmt的路径。您正在运行sh
,而不是bash
-/bin/sh:gmt:command not found
表明gmt
所在的目录不是PATH
环境变量的一部分。请尝试给出gmt
程序的完整路径名。@cdarke我给它的是gmt的完整路径。我想可能是我没有正确存储输出。下面是命令输出在shell打印坐标中的内容。这是一个stdout和stderr的元组。您需要坐标[0]。简单地在空白处拆分字符串不是一个好主意;假设文件名是foobar.txt
?我同意你的看法。简单地在空白处拆分字符串不是一个好主意;假设文件名是foobar.txt
?我必须同意你的看法。