我的问题与之前的问题有关 - Python subprocess usage
我正在尝试使用python
运行此命令nccopy -k 4" http://www.esrl.noaa.gov/psd/thredds/dodsC/Datasets/ncep.reanalysis2/pressure/air.2014.nc?air[408:603][2][20:34][26:40]" foo.nc
当我运行上面的命令时,我应该能够在我的磁盘上看到一个名为foo.nc的文件或网络错误,指出无法访问该URL或找不到远程URL。
目前ESRL NOAA服务器已关闭 - 所以当我运行上述命令时,我得到了
语法错误,意外的$ end,期待SCAN_ATTR或SCAN_DATASET或SCAN_ERROR 上下文:^ NetCDF:访问失败 位置:文件nccopy.c; 1348行
运行python脚本时我应该得到同样的错误
这是我的代码,我无法弄清楚如何进一步 -
我试过分裂" -k 4"两个参数并删除引号,我仍然得到此错误nccopy:无效格式:4
print(sys.argv)data.py
的结果[' data.py',' -k',' 4',' http://www.esrl.noaa.gov/psd/thredds/dodsC/Datasets/ncep.reanalysis2/pressure/air.2014.nc?air[480:603][20:34][26:40]',&# 39; foo.nc']
import numpy as np
import subprocess
import sys
url = '"http://www.esrl.noaa.gov/psd/thredds/dodsC/Datasets/ncep.reanalysis2/pressure/air.2014.nc?air[408:603][2][20:34][26:40]"'
outputFile = 'foo.nc'
arg1 = "-k 4"
arg3 = url
arg4 = outputFile
print (input)
subprocess.check_call(["nccopy",arg1,arg3,arg4])
答案 0 :(得分:2)
而不是arg1 =“ - k 4”,而是使用两个参数。
import subprocess
url = 'http://www.esrl.noaa.gov/psd/thredds/dodsC/Datasets/ncep.reanalysis2/pressure/air.2014.nc?air[408:603][2][20:34][26:40]'
outputFile = 'foo.nc'
arg1 = "-k"
arg2 = "4"
arg3 = url
arg4 = outputFile
subprocess.check_call(["nccopy", arg1, arg2, arg3, arg4])
答案 1 :(得分:2)
这里有两个困境
一个是子进程处理您的参数并尝试使用4
作为单独的参数。
另一个是系统调用仍然遵循正常的shell规则,这意味着将为metacharacters即特殊字符解析参数和命令。在这种情况下,您要换行[
和]
。
您需要将每个参数及其值分隔为参数列表中的单独对象,例如-k 4
应为['-k', '4']
,并且您需要在{{1}中包装参数/值而不是'...'
。
试试这个,"..."
为你做了咕噜咕噜的工作,我在URL周围交换了封装字符:
shlex.split()
答案 2 :(得分:1)
如果你有一个工作的shell命令运行一个带有多个参数的程序并且你想对它进行参数化,例如,使用变量文件名而不是硬编码值,那么你可以使用shlex.split()
创建一个列表命令行参数,您可以传递给subprocess
模块并用变量替换所需的参数,例如:
>>> shell_command = "python -c 'import sys; print(sys.argv)' 1 't w o'"
>>> import shlex
>>> shlex.split(shell_command)
['python', '-c', 'import sys; print(sys.argv)', '1', 't w o']
要使用与父脚本相同的Python解释器运行命令,可以使用sys.executable
,我们可以传递variable
而不是'1'
:
#!/usr/bin/env python
import random
import sys
import subprocess
variable = random.choice('ab')
subprocess.check_call([sys.executable, '-c', 'import sys; print(sys.argv)',
variable, 't w o'])
注意:
shlex.split()
't w o'
内没有引号,即使用't w o'
代替'"t w o"'
或"'t w o'"
subprocess
模块默认情况下不运行shell,因此您不需要转义shell元字符,例如命令行参数中的空格。反过来说,如果你的命令使用了一些shell功能(例如,文件模式),那么要么重新实现Python中的相应功能(例如,使用glob
模块),要么使用shell=True
并将命令作为字符串传递原样。在这种情况下,您可能需要pipes.quote()
来转义变量参数。 Wildcard not working in subprocess call using shlex