Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Python中调用bash命令返回错误,但在终端中有效_Python_Bash - Fatal编程技术网

在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
?我必须同意你的看法。