shell getopt 讲解

#!/bin/bash

main(){

    # -o 注册短格式选项,选项值为可选的选项,选项值只能紧接选项而不可使用任何符号将其他选项隔开
    # --long注册长格式选项, 如果是可选项,那选项值只能使用 = 号连接
    # 选项后没有冒号表示后面绝对不带任何参数了,如:--help 选项; 冒号表示后面接参数值,脚本的下一个参数被解析成选项值;两个冒号表示值可选,选项与选项值连写表示有值,分开表示无值。
    set -- $(getopt -o i:p::h --long ip:,port::,help -- "$@")

    #选项参数
    while true
    do
        case "$1" in
        -i|--ip)        echo "ip: $2"; shift;;
        -p|--port)      echo "port: $2"; shift;;
        -h|--help)      echo "
                        Usage:
                        -i, --ip    target server ip
                        -p, --port  target service port
                        -h, --help  display this help and exit
                        "; return 0;;
        --)             shift; break;; #这里跳出循环,-- 用作一个结束标识
        *)              echo "无效选项:$1";;
        esac
        shift

    done

    #剩余参数
    for param in "$@"
    do
        echo "Param: $param"
    done

}
 
echo '正确用法1:main -i 192.168.3.1 -p3306 nginx-server nginx.conf'
main -i 192.168.3.1 -p3306 nginx-server nginx.conf
echo '============================'

echo '正确用法2:main --ip 192.168.3.1 --port=3306 nginx-server nginx.conf'
main --ip 192.168.3.1 --port=3306 nginx-server nginx.conf
echo '============================'

echo '错误用法1:main -p 3306 nginx-server nginx.conf'
echo '原因: -p 是短可选项,选项与值不能分开'
main -p 3306 nginx-server nginx.conf
echo '============================'


echo '错误用法2:main -p 3306 nginx-server nginx.conf'
echo '原因: --port 是长可选项,选项与值只能用等号连接'
main --port 3306 nginx-server nginx.conf

下面,封装一个函数,函数实现功能是用一个文件覆盖另一个文件。通常,我们喜欢备份配置文件,从备份中恢复,就非常简单了。

cover default.conf.bak  default.conf
cover default.conf.bak 
cover -r default.conf.bak

function cover(){

    set -- $(getopt -u -o rh --long rm,help -- $@)
    #echo $@   
    local rm=false
    for i in "$@"
    do
        case "$1" in
        -r|--rm)    rm=true;;
        -h|--help)
echo "cover [option] <source> [target]
功能:用一个 source 文件覆盖 target 文件,如果省略 target,则根据 source.bak 自动推导
用法:
    cover source.conf target.conf
    cover config.conf.bak 
选项:
    -r, --rm    删除源文件
    -h, --help  帮助"; return 0
        ;;
        --)         shift 1; break;;
        *)          echo "无效选项:$1"; return 0 ;;
        esac
        shift 1

    done

    local source=$1
    local target=$2
    [ -z "$target" ] && target="${source%.bak}"
    sudo bash -c "cat $source > $target"

    [ $rm == 'true' ] && { [ "$?" -eq 0 ] && sudo rm $source; }

}
原文地址:https://www.cnblogs.com/zbseoag/p/14049158.html