Python脚本:使用子流程运行具有多个参数的脚本

Python脚本:使用子流程运行具有多个参数的脚本,python,arguments,subprocess,Python,Arguments,Subprocess,我的问题与先前的问题有关— 我正在尝试使用python运行此命令 nccopy-k 4英寸foo.nc 当我运行上述命令时,我应该能够在我的磁盘上看到一个名为foo.nc的文件,或者看到一个网络错误,说明无法访问该URL或找不到远程URL 目前ESRL NOAA服务器已关闭-因此当我运行上述命令时 语法错误,意外的$end,应为扫描属性或扫描数据集或扫描错误 背景:^ NetCDF:访问失败 位置:文件nccopy.c;第1348行 当我运行python脚本时,应该会出现相同的错误 这是我所拥有

我的问题与先前的问题有关—

我正在尝试使用python运行此命令

nccopy-k 4英寸foo.nc

当我运行上述命令时,我应该能够在我的磁盘上看到一个名为foo.nc的文件,或者看到一个网络错误,说明无法访问该URL或找不到远程URL

目前ESRL NOAA服务器已关闭-因此当我运行上述命令时

语法错误,意外的$end,应为扫描属性或扫描数据集或扫描错误 背景:^ NetCDF:访问失败 位置:文件nccopy.c;第1348行

当我运行python脚本时,应该会出现相同的错误

这是我所拥有的代码,我无法准确地理解如何继续-

我尝试将“-k4”拆分为两个参数并删除引号,但仍然出现以下错误nccopy:invalid format:4

打印结果(sys.argv)data.py

['data.py','-k','4','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])
使用两个参数代替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])
另请参见此处,使用两个参数代替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])

另请参见此处

这里有两个难题。
一个是子流程处理您的参数并尝试使用
4
作为单独的参数

另一个原因是系统调用仍然遵循正常的shell规则,这意味着参数和命令将被解析为特殊字符。在本例中,您正在包装
[
]

因此,您需要将每个参数及其值分离到参数列表中的单独对象中,例如
-k4
应该是
['-k',4']
,您需要将参数/值包装在
'.'
中,而不是
'.

试试这个,
shlex.split()
为您执行grunt操作,我在URL周围交换了封装字符:

import numpy as np
import subprocess
import sys
import shlex

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'
command_list = shlex.split('nccopy -k 4 ' + url + ' ' + outpufFile)

print(command_list)

subprocess.check_call(command_list)

这里有两个难题。
一个是子流程处理您的参数并尝试使用
4
作为单独的参数

另一个原因是系统调用仍然遵循正常的shell规则,这意味着参数和命令将被解析为特殊字符。在本例中,您正在包装
[
]

因此,您需要将每个参数及其值分离到参数列表中的单独对象中,例如
-k4
应该是
['-k',4']
,您需要将参数/值包装在
'.'
中,而不是
'.

试试这个,
shlex.split()
为您执行grunt操作,我在URL周围交换了封装字符:

import numpy as np
import subprocess
import sys
import shlex

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'
command_list = shlex.split('nccopy -k 4 ' + url + ' ' + outpufFile)

print(command_list)

subprocess.check_call(command_list)

如果您有一个运行具有多个参数的单个程序的工作shell命令,并且希望对其进行参数化,例如,使用变量文件名而不是硬编码值,则可以使用
shlex.split()
创建可传递给
子流程的命令行参数列表
模块,并用变量替换所需参数,例如:

>>> 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
,我们可以传递
变量,而不是
'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()
  • 'two'
    中没有引号,即使用
    'two'
    代替
    “'two'”
    “'two'”

子流程
模块默认情况下不运行shell,因此不需要转义shell元字符,例如命令行参数中的空格。相反,如果您的命令使用一些shell功能(例如,文件模式),则可以在Python中重新实现相应的功能(例如,使用
glob
module)或使用
shell=True
并按原样将命令作为字符串传递。在这种情况下,您可能需要
pipes.quote()
,以转义变量参数

如果您有一个运行具有多个参数的单个程序的shell命令,并且希望对其进行参数化,例如,使用变量文件名而不是硬编码值,则可以使用
shlex.split()
创建可传递给
子流程的命令行参数列表
模块,并用变量替换所需参数,例如:

>>> 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
,我们可以传递
变量,而不是
'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()
  • 'two'
    中没有引号,即使用
    'two'
    代替
    “'two'”
    “'two'”

子流程
模块默认情况下不运行shell,因此不需要转义shell元字符,例如命令行参数中的空格。相反,如果您的命令使用一些shell功能(例如,文件模式),则可以在Python中重新实现相应的功能(例如,使用
glob
module)或使用
shell=True
并按原样将命令作为字符串传递。在这种情况下,您可能需要
pipes.quote()
,以转义变量参数

首先,使用,然后使用
Popen()
而不是
check\u call()
,如果可能的话。另外,您的问题是没有将
-k
4
分开。子流程自动尝试为每个参数元素插入一个空格。当调用系统命令时,也可以尝试使用这个
[“nccopy”、'-k',4']
,传统的shell逻辑仍然适用,这意味着
将启用变量和字符的解析,而as
在p