shell腳本傳可選參數 getopts 和 getopt的方法


寫了一個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/bash
 
while getopts "a:" opt; do
  case $opt in
    a)
      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/bash
 
while getopts "a:b:cdef" opt; do
  case $opt in
    a)
      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/bash
 
while getopts "a:" opt; do
  case $opt in
    a)
      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/bash
 
while getopts ":a:" opt; do
  case $opt in
    a)
      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 ]; then
    echo "Terminating..."
    exit 1
fi

#echo $ARGS
#將規范化后的命令行參數分配至位置參數($1,$2,...)
eval set -- "${ARGS}"

while true;
do
    case "$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
            ;;

        --)
            shift
            break
            ;;
        *)
            echo "Internal error!"
            exit 1
            ;;
    esac

done

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:-}

這一部分為輸入參數對應的字符

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.sh

print ${1:-hello}

print ${2:-kshell}

$sh myscript.sh

hello

kshell

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM