寫了一個shell腳本,需要向shell腳本中傳參數供腳本使用,達到的效果是傳的參數可以是可選參數
下面是一個常規化的shell腳本:
echo "執行的文件名為: $0";echo "第一個參數名為: $1";echo "第二個參數名為: $2"
正常的向shell腳本中傳參數的方法為:
./test.sh 1 2 3
最后執行的結果為:
?
執行的文件名為: ./test.sh第一個參數名為: 1第二個參數名為: 2
但是這個是只能按照順序傳遞參數,并且不能傳遞可選參數,然后查資料,發現了一個shell的getopts 用法
?首先貼個例子
[hello@Git shell]$ bash test.sh -a hello this is -a the arg is ! hello [hello@Git shell]$ more test.sh #!/bin/bashwhile getopts "a:" opt; docase $opt ina)echo "this is -a the arg is ! $OPTARG" ;;\?)echo "Invalid option: -$OPTARG" ;;esac done
getopts一共有兩個參數,第一個是-a這樣的選項,第二個參數是 hello這樣的參數。
選項之間可以通過冒號:進行分隔,也可以直接相連接,:表示選項后面必須帶有參數,如果沒有可以不加實際值進行傳遞
例如:getopts ahfvc: option表明選項a、h、f、v可以不加實際值進行傳遞,而選項c必須取值。使用選項取值時,必須使用變量OPTARG保存該值。
[hello@Git shell]$ bash test.sh -a hello -b this is -a the arg is ! hello test.sh: option requires an argument -- b Invalid option: - [hello@Git shell]$ bash test.sh -a hello -b hello -c this is -a the arg is ! hello this is -b the arg is ! hello this is -c the arg is ! [hello@Git shell]$ more test.sh #!/bin/bashwhile getopts "a:b:cdef" opt; docase $opt ina)echo "this is -a the arg is ! $OPTARG" ;;b)echo "this is -b the arg is ! $OPTARG" ;;c)echo "this is -c the arg is ! $OPTARG" ;;\?)echo "Invalid option: -$OPTARG" ;;esac done [hello@Git shell]$
執行結果結合代碼顯而易見。同樣你也會看到有些代碼在a的前面也會有冒號,比如下面的
情況一,沒有冒號:
[hello@Git shell]$ bash test.sh -a hello this is -a the arg is ! hello [hello@Git shell]$ bash test.sh -a test.sh: option requires an argument -- a Invalid option: - [hello@Git shell]$ more test.sh #!/bin/bashwhile getopts "a:" opt; docase $opt ina)echo "this is -a the arg is ! $OPTARG" ;;\?)echo "Invalid option: -$OPTARG" ;;esac done [hello@Git shell]$
情況二,有冒號:
[hello@Git shell]$ bash test.sh -a hello this is -a the arg is ! hello [hello@Git shell]$ bash test.sh -a [hello@Git shell]$ more test.sh #!/bin/bashwhile getopts ":a:" opt; docase $opt ina)echo "this is -a the arg is ! $OPTARG" ;;\?)echo "Invalid option: -$OPTARG" ;;esac done
情況一輸入 -a 但是后面沒有參數的的時候,會報錯誤,但是如果像情況二那樣就不會報錯誤了,會被忽略。
while getopts ":a:bc" opt? #第一個冒號表示忽略錯誤;字符后面的冒號表示該選項必須有自己的參數?
參考?https://blog.csdn.net/xluren/article/details/17489667
但是這樣還是無法滿足可以輸入可選參數的要求,這樣輸入的參數名稱也是固定的,參數的數量也是固定的,然后接下來了解了shell 的getopt用法。
看過官方文檔后,自己寫了個小demo
#!/bin/bash#獲取對應的參數 沒有的話賦默認值 ARGS=`getopt -o a::b::l::n::t::p:: --long along::,blong::,llong::,plong:: -n 'example.sh' -- "$@"` if [ $? != 0 ]; thenecho "Terminating..."exit 1 fi#echo $ARGS #將規范化后的命令行參數分配至位置參數($1,$2,...) eval set -- "${ARGS}"while true; docase "$1" in-a|--along)case "$2" in"")project1_name=master;shift 2;;;*)project1_name=$2;shift 2;;;esac;;-b|--blong)case "$2" in"")project2_name=master;shift 2;;*)project2_name=$2;shift 2;;;esac;;-l|--llong)case "$2" in"")layer=layer_1;shift 2;;*)layer=$2;shift 2;;;esac;;-n)case "$2" in"")number=1000;shift 2;;*)number=$2;shift 2;;;esac;;-t)case "$2" in"")select_type=top;shift 2;;*)select_type=$2;shift 2;;;esac;;-p)case "$2" in"")data_point=;shift 2;;*)data_point=$2;shift 2;;;esac;;--)shiftbreak;;*)echo "Internal error!"exit 1;;esacdoneproject1_name=${project1_name:-master} project2_name=${project2_name:-master} layer=${layer:-layer_1} number=${number:-100} select_type=${select_type:-top} data_point=${data_point:-}
這一部分為輸入參數對應的字符
a::b::l::n::t::p::
?
#-o表示短選項,兩個冒號表示該選項有一個可選參數,可選參數必須緊貼選項,如-carg 而不能是-c arg
#--long表示長選項
一目了然,首先是根據傳遞過來的 是 -a? 還是 -b? -l 進行判斷,如果只有-a后面沒有參數的話 則賦默認值,同時在
project1_name=${project1_name:-master} project2_name=${project2_name:-master} layer=${layer:-layer_1} number=${number:-100} select_type=${select_type:-top} data_point=${data_point:-}
這一步 也進行了默認值的賦值操作。如果上面沒有 project1_name? 則賦值為master
例子如下:
參數的默認值設置$cat myscript.shprint ${1:-hello}print ${2:-kshell}$sh myscript.shhellokshell
?