简体   繁体   English

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

[英]Python script : Running a script with multiple arguments using subprocess

My question is related to this earlier question - Python subprocess usage 我的问题与此先前的问题有关-Python子进程用法

I am trying to run this command using python 我正在尝试使用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 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

When I run the above command I should be able to see a file called foo.nc on my disk or a network error stating unable to access that URL or remote URL not found. 当我运行上述命令时,我应该能够在磁盘上看到一个名为foo.nc的文件,或者出现网络错误,指出无法访问该URL或找不到远程URL。

Currently the ESRL NOAA server is down - so when I run the above command I get 当前ESRL NOAA服务器已关闭-因此,当我运行以上命令时,

syntax error, unexpected $end, expecting SCAN_ATTR or SCAN_DATASET or SCAN_ERROR context: ^ NetCDF: Access failure Location: file nccopy.c; 语法错误,意外的$ end,期望使用SCAN_ATTR或SCAN_DATASET或SCAN_ERROR上下文:^ NetCDF:访问失败位置:文件nccopy.c; line 1348 1348行

I should get the same error when I run the python script 我在运行python脚本时应该遇到相同的错误

This is the code I have and I am unable to figure out exactly how to proceed further - 这是我的代码,我无法确切知道如何继续进行操作-

I tried splitting up "-k 4" into two arguments and removing the quotes and I still get this error nccopy : invalid format : 4 我尝试将“ -k 4”拆分为两个参数并删除引号,但仍然收到此错误nccopy:无效格式:4

Results of print(sys.argv) data.py 打印结果(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] ', 'foo.nc'] ['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] ','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])

Instead of arg1 = "-k 4", use two arguments instead. 代替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])

See also here Python subprocess arguments 另请参阅此处Python子流程参数

There's two dilemmas here. 这里有两个难题。
One being that subprocess processes your arguments and tries to use 4 as a separate argument. 一个子进程处理您的参数,并尝试使用4作为单独的参数。

The other being that system calls still goes under normal shell rules, meaning that parameters and commands will be parsed for metacharacters aka special characters. 另一个是系统调用仍然遵循常规的shell规则,这意味着将对元字符 (也称为特殊字符)进行参数和命令的解析。 In this case you're wrapping [ and ] . 在这种情况下,您要包装[]

There for you need to separate each parameters and it's value into separate objects in the parameter-list, for instance -k 4 should be ['-k', '4'] and you need to wrap parameters/values in '...' instead of "..." . 在那里,您需要将每个参数及其值分隔到参数列表中的单独对象中,例如-k 4应该为['-k', '4']并且需要将参数/值包装在'...'而不是"..."

Try this, shlex.split() does the grunt work for you, and i swapped the encapsulation characters around the URL: 尝试一下, shlex.split()可以为您工作,我在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)

If you have a working shell command that runs a single program with multiple arguments and you want to parameterized it eg, to use a variable filename instead of the hardcoded value then you could use shlex.split() to create a list of command-line arguments that you could pass to subprocess module and replace the desired argument with a variable eg: 如果您有一个运行中的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']

To run the command using the same Python interpreter as the parent script, sys.executable could be used and we can pass a variable instead of '1' : 要使用与父脚本相同的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'])

Note: 注意:

  • one command-line argument per list item 每个列表项一个命令行参数
  • no shlex.split() in the final code 最终代码中没有shlex.split()
  • there are no quotes inside 'tw o' ie, 'tw o' is used instead of '"two"' or "'tw o'" 'tw o'中没有引号,即使用'tw o'代替'"two"'"'tw o'"

subprocess module does not run the shell by default and therefore you don't need to escape shell meta-characters such as a space inside the command-line arguments. subprocess模块默认情况下不运行外壳程序,因此您不需要转义外壳程序元字符,例如命令行参数内的空格。 And in reverse, if your command uses some shell functionality (eg, file patterns) then either reimplement the corresponding features in Python (eg, using glob module) or use shell=True and pass the command as a string as is. 相反,如果您的命令使用了某些Shell功能(例如,文件模式),则可以在Python中重新实现相应的功能(例如,使用glob模块),或者使用shell=True并按原样将命令作为字符串传递。 You might need pipes.quote() , to escape variable arguments in this case. 在这种情况下,您可能需要pipes.quote()来转义变量参数。 Wildcard not working in subprocess call using shlex 通配符在使用shlex的子进程调用中不起作用

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM