The Issue of the Day Before

shell script 參數使用範例

shell -

要傳參數給 shell script,如果只是簡單的只有一個,很方便的取用 $1 即可。 但在需要的參數有多個時,要求使用該 script 的人都背誦參數順序是不合理的。 這時 getopts 便可派上用場。

Why

有時候想要編寫的 shell script 具有更好的通用性,這時接受外部的參數來協助 script 進行作業,是一個好方法。

一般有兩個方式,一個是設定環境參數 export <args1>

另一個是使用 $1, $2,…​ 取得 script command 後以空白分隔的值。

使用環境參數容易混亂不容易管理,容易忘記移除。

但要傳參數給 shell script,如果只是簡單的只有一個,很方便的取用 $1 即可。 但有多個時,不可能要求使用該 script 的人都背誦參數順序。這時 getopts 便可派上用場。

shell script 中, $0 是代表 shell script 本身的名稱,而 $1 就是命令後隔空白字元的第一個值。 其他,就順延為 $2, $3…​。

How

test.sh
help() {
    echo "Usage:"
    echo "test.sh [-a first] [-b] [-c third]"
    echo "Description:"
    echo "-h help, description"
    exit -1
}

while getopts "a:bc:h" opt // (1)
do
    case $opt in
      a)
      First=$OPTARG  // (2)
      FirstIndex=$OPTIND // (3)
      ;;
      b)
      Second=$OPTARG
      SecondIndex=$OPTIND
      ;;
      c)
      Third=$OPTARG
      ThirdIndex=$OPTIND
      ;;
      h) help
      ;;
      ?)  // (4)
      echo "unknown error"
      help
      exit 1
    esac
done

echo "First Argv: $First, Index: $FirstIndex"
echo "Second Argv: $Second, Index: $SecondIndex"
echo "Third Argv: $Third, Index: $ThirdIndex"
  1. getopts 後面接一個字串,指示他如何解析參數。

  2. -a 後有值時,該值會放在 $OPTARG

  3. $OPTIND 下一個參數的索引值,即 ${n+1}

  4. 當出現不在 getopts 字串中的參數時,會被執行。

解析 getopts 字串,當英文字母後有 : 時,代表他後面必須要接一個值。 而當英文字母後沒有 : 時,代表他是一個布林值,$opt 會被設定但後面不能接一個值。

必須注意的是,若輸入的參數不合上面的邏輯,則對 $OPTARG 的解析會出錯。

例如,

>./test.sh -a -b -c three
// First Argv: -b, Index: 3
// Second Argv: , Index:
// Third Argv: three, Index: 5

-a 後面無值,所以原本作為指示的 -b 變成 -a 的值。

又,

./test.sh -a hi -b world -c three
// First Argv: hi, Index: 3
// Second Argv: , Index: 4
// Third Argv: , Index:

-b 後面應該無值卻有值,所以原本應該有的 -c 就不見了。

正確的參數用法,

> ./t.sh -a hi -b -c world
// First Argv: hi, Index: 3
// Second Argv: , Index: 4
// Third Argv: world, Index: 6
閱讀在雲端