2015-09-14 49 views
1

在我的bash腳本中,我想使用getopts來解析命令行選項。如何讓bash getopts無法將option選項作爲選項參數

我第一次嘗試,學習如何使用它,如下所示:

#!/bin/bash 

v_option_arg="" 
r_option_arg="" 
h_option_arg="" 

function get_opt_args() { 
    while getopts ":v:r:h:" opt 
    do 
     case $opt in 
     "v") 
      v_option_arg="$OPTARG" 
      ;; 
     "h") 
      h_option_arg="$OPTARG" 
      ;; 
     "r") 
      r_option_arg="$OPTARG" 
      ;; 
     "?") 
      echo "Unknown option -$OPTARG" 
      exit 1 
      ;; 
     ":") 
      echo "No argument value for option -$OPTARG" 
      ;; 
     *) 
      # Should not occur 
      echo "Unknown error while processing options" 
      ;; 
     esac 
    done 
    shift $((OPTIND-1)) 
} 

get_opt_args [email protected] 
if [ ! -z "$v_option_arg" ]; then 
    echo "Argnument value for option -v: $v_option_arg" 
fi 
if [ ! -z "$r_option_arg" ]; then 
    echo "Argnument value for option -r: $r_option_arg" 
fi 
if [ ! -z "$h_option_arg" ]; then 
    echo "Argnument value for option -h: $h_option_arg" 
fi 
$ bash testopts.sh -v 1 
Argnument value for option -v: 1 
$ bash testopts.sh -r 2 
Argnument value for option -r: 2 
$ bash testopts.sh -h 3 
Argnument value for option -h: 3 
$ bash testopts.sh -v 1 -r 2 -h 3 
Argnument value for option -v: 1 
Argnument value for option -r: 2 
Argnument value for option -h: 3 
$ bash testopts.sh -v 
No argument value for option -v 
$ bash testopts.sh -a 
Unknown option -a 

這似乎能夠成功。

接下來,我省略參數測試我的腳本的健壯性:

$ bash testopts.sh -v -r 2 
Argnument value for option -v: -r 

這不是我所期待的。我怎樣才能區分一個選項和一個選項參數的差異?

我想讓我的腳本更健壯,這樣如果有一個選項沒有它的參數,我可以發出一個合適的錯誤信息。

注意:每個選項都必須有一個選項參數。

我可以用getopts這麼做嗎?

+0

您將-v選項聲明爲需要參數。所以'getopt'認爲'-r'是選項'-v'的強制參數。如果你想讓'-v'有一個可選的參數,在optstring中使用'v ::'而不是'v:'。 –

+0

@RenaudPacalet'::'行爲是GNU擴展,而不是POSIX標準。 – rojomoke

+0

@rojomoke你說得對。 –

回答

3

man bash,SHELL內建命令getopts的:

optstring包含要識別的選項字符;如果一個字符後面跟着一個冒號,則該選項應該有一個參數,該參數應該用空格分隔。

從您的腳本:

while getopts ":v:r:h:" opt 

你告訴bash明確表示-v期待的理由。在-v -r 2的情況下,-r-v的參數,其中2作爲腳本的非選項參數。

按設計工作,這是getopts能力的限制。

可以做的是檢查什麼,如果參數-v是數字(因爲它似乎是你的腳本需要什麼),並在給定的情況下,通知用戶-v確實需要一個數字,那-r是不是。但是這是你的腳本在"v")的情況下需要做的事情,而不是getopts可以處理的事情。

case $opt in 
    "v") 
     v_option_arg="$OPTARG" 
     if [[ ! "${v_option_arg}" =~ ^[0-9]*$ ]] 
     then 
      echo "Error: Option '-v' expects numeric argument, you gave: ${v_option_arg}" 
      exit 1 
     fi 
     ;; 
+0

好吧,我明白了。感謝您的患者。 – lojunren

相關問題