Hom's Blog


Python和Shell的getopt

getopt是个好基础的函数用来解析命令行参数, 功能也很简单…先介绍shell的, 了解以后就很容易明白python版的啦.

getopt command in Shell

shift

首先要了解一个内建命令(csh/sh): shift

首先要回忆, $* 代表所有参数(一个字符串), $@ 代表所有参数(可放字符串内,代表数组) $# 代表所有参数个数. $0....9 代表0到9参数.

当输入参数个数多于9个时, 只能用 $*$@ 获取后面的参数了. shift则是帮助”消除掉”前面的参数,使$0....9发生移位,从而可以帮助一个一个参数获取.

shift N (默认N=1) 移动 N 个命令行参数. 例如shift 3, 则本来的 $4 变成了 $1 .前面的几个则消失掉.$*$@ 也会受影响.

getopts (sh内建,csh没有)

  • 基本语法: getopts optstring name [arg ...], 只支持短选项-f,不支持长选项–file.
  • 原理: 每次调用getopts后都解析一次命令行参数(要是给定arg部分就解析该部分而不是命令行参数),找到选项名就和给定选项名字符串optstring内的进行匹配,要是匹配成功,就把选项名存到name中并将其对应选项参数值存到$OPTARG shell变量中,而下一个要解析的位置则存到$OPTINT中,方便getopts进行下次分析.找不到对应选项或最后一个选项时,选项名为?.
  • 支持: -a value -b -c, -avalue -bc, -bca value等常见解析方法.不支持长参数名–opt这种.
  • optstring: opt[:] 的方式,对应选项名,后跟:表示跟参数,不跟:表示无参数(此时仍可抓到选项到name).注意:
    • a: 表示跟参数,后面参数的个数必须为1,多了下一个就解析不了;少了会报错如”option requires an argument – f”.
    • optstring不能含有?,因为其有特殊意义.
  • 解析到末尾, 无-非参数的项以及 --项都会导致解析终止, 返回name=?以及OPTINT到下一个位置,并unset掉OPTARG. 退出值为1, 因此可以用while循环来控制读取(0正常返回,才执行)
  • 解析不了的选项会报错, 但返回值仍然为0, 解析继续. 返回name=?以及OPTINT到下一个位置,并unset掉OPTARG.
  • 设置$OPTINT的值可以控制解析的变化,配合SHIFT也可以有神奇作用.
  • 在optstring开头加: 可以忽略所有报错.如:a:b. 处理行为也有变化: 不存在的选项,name=?,OPTARG=选项名; 该跟值而没有给值, name=:,OPTARG=选项名.
  • 另外有写说法说开头使用+什么的, 但经测试在mac无效.
  • 英文参考: getopts帮助,一个教程

例子:

#!/bin/bash
## 常用while+case来使用
while getopts 'd:Dm:f:t:' OPT
do
    case $OPT in
        d)
            DEL_DAYS="$OPTARG";;
        D)
            DEL_ORIGINAL='yes';;
        f)
            DIR_FROM="$OPTARG";;
        m)
            MAILDIR_NAME="$OPTARG";;
        t)
            DIR_TO="$OPTARG";;
       \?)
            echo "Usage: `basename $0` [options] filename";;
    esac
done
## 调整$1-$9,删掉已解释选项,
shift $(($OPTIND - 1))

getopt (外部程序,不一定有,例如mingw就没有)

getopt支持长参数,甚至-long的用法. 用起来要复杂一些..mac版本和linux也有差异, 通用性差,不建议使用.

  • 基本用法: args=`getopt optstring $*`;set -- $args; 循环带shift处理
  • 原理: getopt先把命令行参数进行分析, 分析后将新的命令行参数字符串赋给args,随后再将args作为命令行参数(set 一句), 然后再逐一对命令行参数进行分析(需要自行设定shift).相比getopts要复杂在要手动解析参数并shift.
  • 详细用法可以参考ref1,ref2,ref3

getopt module in Python

只有两个函数: getopt(args,options[,long_options])gnu_getopt(args,options[,long_options]), 后者比前者好在支持遇到非选项参数不会停止解析.

  • args: 就是参数列表, 默认sys.argv[1:].
  • options: 短选项字符串,不带-.类似于linux的方式,”c:d:ab”这样,:表示该选项带参数. getopt中一旦解析遇到非选项参数(即没定义参数),后面全部作为非选项参数处理; 而gnu_getopt则不会,即使遇到非选项参数也会继续解析,除非options字符串以”+”开头.
  • long_options: 长选项列表,不带-. 每项就是长选项名. 需要参数的后面跟=.例如[“file=”,”rewrite”]这样. 使用命令时,–fo可以匹配–fout这样,只要没有歧义.
  • 返回: ( [(option,value)…], other_args) ,前面是选项和值的元组的列表, 后面是没被解析剩余的参数. 注意选项是带---

Reference

  1. Python官网帮助
  2. Python 源码


◆ 本文地址: http://platinhom.github.io/2015/10/03/getopt/, 转载请注明 ◆

前一篇: VB基础-VBA篇
后一篇: Python分析命令行输入:OptParse模块


Contact: Hom / 已阅读()
Source 类别: Coding  标签: Python  Bash