[Linux] 使用 getopt 在 shell script 中解析命令列參數

[Linux] 使用 getopt 在 shell script 中解析命令列參數

最近學到在 Linux 上可以用 getopt 來輔助解析命令列參數 (command line parameters)~

getopt 是一個 command line 的 tool (跟 Linux 內建的 getopts 不一樣),

可以指定所謂的 short/long option 給 getopt,

getopt 會把符合的 short/long options 整理起來,並且把其他非 – 開頭的參數排在後面,

因此可以很方便的用它來分析 command line options~

 

舉例來說,下面的指令用 -o 指定了 -i, -o, -s 三種 short option,

其中 -i 和 -o 後面一定要帶一個參數 (單一 :),而 -s 後面則不需要帶參數~

–long 用來設定 long options,這邊分別定義了 –input, –output, –strip,

其中 –input 和 –output 後面一定要帶一個參數 (單一 :),而 –strip 後面則不需要帶參數~

testuser@localhost ~ getopt -o i:o:s --long input:,output:,strip -- aaa -i "input file" "bbb ccc" -o "output file" -s ddd
-i 'input file' -o 'output file' -s -- 'aaa' 'bbb ccc' 'ddd'

 

可以看到 getopt 幫我們將命令列參數整理了一下,

有 – 開頭的 short/long option 排在前面,接著是一個 –,接著就是非 – 開頭的參數~

用在 shell script 裡時,可以用下面的程式來解析:

GETOPT_RESULT=$(getopt -o i:o:s --long input:,output:,strip -- "$@" 2>&1) || exit
eval set -- "${GETOPT_RESULT}"
# Read parsed command lines
while true
do
    case "$1" in
-i|--input)
INPUT_FILE="$2"
shift 2
;;
-o|--output)
OUTPUT_FILE="$2"
shift 2
;;
-s|--strip)
FLAG_STRIP=1
shift
;;
--)
# Currently we don't care about positional parameters
shift
            break
;;
*)
# Should not go in here.
break
;;
esac
done

 

如果給錯了 short/long option,getopt 也會藉由 stderr 來顯示錯誤~

例如用了 -x 選項時,因為我們並沒有將 -x 宣告為合法的選項 (用 -o 或 –long),

因此 getopt 會傳回錯誤,但 stdout 還是會將可以解析的部分吐出來:

testuser@localhost ~ getopt -o i:o:s --long input:,output:,strip -- aaa -x -i "input file" "bbb ccc" -o "output file" -s ddd
getopt: invalid option -- 'x'
-i 'input file' -o 'output file' -s -- 'aaa' 'bbb ccc' 'ddd'

 

另一點要注意的是,getopt 似乎舊版並不支援參數裡有空白字元,

因此後來有所謂的加強版 (現在一般的 Linux 上的應該都是)~

要確認是加強版的話,可以用 -T 選項,檢查 exit code == 4 就是新版的了:

testuser@localhost ~ getopt -T
testuser@localhost ~ echo $?
4

 

參考資料:

Using getopts in bash shell script to get long and short command line options

Command Line Options: How To Parse In Bash Using “getopt”

(本頁面已被瀏覽過 1,038 次)

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。

這個網站採用 Akismet 服務減少垃圾留言。進一步瞭解 Akismet 如何處理網站訪客的留言資料