Python脚本:使用子进程

时间:2016-05-30 06:30:05

标签: python arguments subprocess

我的问题与之前的问题有关 - 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])

3 个答案:

答案 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])

另见Python subprocess arguments

答案 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