zoukankan      html  css  js  c++  java
  • 使用 getopt 处理命令行长参数

    getopt命令并不是bash的内建命令,它是由util-linux包提供的外部命令。

     getopt 与 getopts 的区别

     getopts 是 shell 内建命令, getopt 是一个独立外部工具

    • getopts 使用语法简单,getopt 使用语法复杂
    • getopts 不支持长参数(长选项,如 --option), getopt 支持
    • getopts 不会重排所有参数的顺序,getopt会重排参数顺序 (getopts 的 shell 内置 OPTARG 这个变量,getopts 通过修改这个变量依次获取参数,而 getopt 必须使用 set 来重新设定位置参数,然后在 getopt 中使用 shift 来依次获取参数)
    • 如果某个参数中含有空格,那么这个参数就变成了多个参数。因此,基本上,如果参数中可能含有空格,那么必须用getopts(新版本的 getopt 也可以使用空格的参数,只是传参时,需要用 双引号 包起来)。
    getopt 命令选项说明:
    1. getopt 命令的选项说明:  
    2. -a 使getopt长选项支持"-"符号打头,必须与-l同时使用  
    3. -l 后面接getopt支持长选项列表  
    4. -n program如果getopt处理参数返回错误,会指出是谁处理的这个错误,这个在调用多个脚本时,很有用  
    5. -o 后面接短参数选项,这种用法与getopts类似,  
    6. -u 不给参数列表加引号,默认是加引号的(不使用-u选项),例如在加不引号的时候 --longopt "select * from db1.table1" $2只会取到select ,而不是完整的SQL语句。  
    7.   选项的使用定义规则类似 getopts :  
    8. 例如  ab:c::    
    9. 意思是:  a 后没有冒号,表示没有可以参数  
    10. b 后跟一个冒号,表示有一个必要的参数  
    11. c 后跟两个冒号,表示有一个可选的参数(参数必须紧挨着选项)  
    12. 长选项的定义相同,但用逗号分割。  
    1. #!/bin/bash  
    2.   
    3. #定义选项, -o 表示短选项 -a 表示支持长选项的简单模式(以 - 开头) -l 表示长选项   
    4. # a 后没有冒号,表示没有参数  
    5. # b 后跟一个冒号,表示有一个必要参数  
    6. # c 后跟两个冒号,表示有一个可选参数(可选参数必须紧贴选项)  
    7. # -n 出错时的信息  
    8. # -- 也是一个选项,比如 要创建一个名字为 -f 的目录,会使用 mkdir -- -f ,  
    9. #    在这里用做表示最后一个选项(用以判定 while 的结束)  
    10. # $@ 从命令行取出参数列表(不能用用 $* 代替,因为 $* 将所有的参数解释成一个字符串  
    11. #                         而 $@ 是一个参数数组)  
    12.       

    getopt命令与getopts命令不同,它实际上是通过将参数规范化来帮助我们处理的。具体的用法,如下面的脚本:

    #!/bin/bash
    
    #echo $@
    
    #-o或--options选项后面接可接受的短选项,如ab:c::,表示可接受的短选项为-a -b -c,其中-a选项不接参数,-b选项后必须接参数,-c选项的参数为可选的
    #-l或--long选项后面接可接受的长选项,用逗号分开,冒号的意义同短选项。
    #-n选项后接选项解析错误时提示的脚本名字
    ARGS=`getopt -o ab:c:: --long along,blong:,clong:: -n 'example.sh' -- "$@"`
    if [ $? != 0 ]; then
        echo "Terminating..."
        exit 1
    fi
    
    #echo $ARGS
    #将规范化后的命令行参数分配至位置参数($1,$2,...)
    eval set -- "${ARGS}"
    
    while true
    do
        case "$1" in
            -a|--along) 
                echo "Option a";
                shift
                ;;
            -b|--blong)
                echo "Option b, argument $2";
                shift 2
                ;;
            -c|--clong)
                case "$2" in
                    "")
                        echo "Option c, no argument";
                        shift 2  
                        ;;
                    *)
                        echo "Option c, argument $2";
                        shift 2;
                        ;;
                esac
                ;;
            --)
                shift
                break
                ;;
            *)
                echo "Internal error!"
                exit 1
                ;;
        esac
    done
    
    #处理剩余的参数
    for arg in $@
    do
        echo "processing $arg"
    done
    

    需要注意的是,像上面的-c选项,后面是可接可不接参数的,如果需要传递参数给-c选项,则必须使用如下的方式:

    #./getopt.sh -b 123 -a -c456 file1 file2 
    Option b, argument 123
    Option a
    Option c, argument 456
    processing file1
    processing file2
  • 相关阅读:
    Git 远程仓库 git remote
    同一台电脑关于多个SSH KEY管理
    dotnet core on Linux 环境搭建及入门demo
    Cannot load JDBC driver class 'com.mysql.jdbc.Driver '
    Mac OS 配置Maven
    Linux中profile、bashrc、bash_profile之间的区别和联系
    如何在Mac的Finder中显示/usr、/tmp、/var等隐藏目录
    Mac OS X 下查看和设置JAVA_HOME
    SSM框架整合(IntelliJ IDEA + maven + Spring + SpringMVC + MyBatis)
    事件
  • 原文地址:https://www.cnblogs.com/klb561/p/9211222.html
Copyright © 2011-2022 走看看