2012-03-21 53 views
4

我想在bash中使用getopts來分析命令行參數,但我無法弄清楚如何實現「默認」行動,如果沒有參數匹配(或沒有cmdline參數給出)。getopts在沒有cmd時打印幫助。行參數匹配

這silghtly簡化的什麼我試過到目前爲止版本:

while getopts v:t:r:s:c: name; 
do 
     case $name in 
     v) VALIDATE=1;; 
     t) TEST=1;; 
     r) REPORT=1;; 
     s) SYNC=1;; 
     c) CLEAR=1;; 
     *) print_help; exit 2;; 
     \?) print_help; exit 2;; 
     esac 
done 

有沒有(簡單)的方法,使其調用print_help; 2號出口;在不匹配的輸入?

回答

3

展望在你的問題和Aditya答案的評論之間,我建議如下:

[getopts]$ cat go 
#!/bin/bash 

function print_help { echo "Usage" >&2 ; } 

while getopts vtrsc name; do 
    case $name in 
     v) VALIDATE=1;; 
     t) TEST=1;; 
     r) REPORT=1;; 
     s) SYNC=1;; 
     c) CLEAR=1;; 
     ?) print_help; exit 2;; 
    esac 
done 

echo "OPTIND: $OPTIND" 
echo ${#@} 

shift $((OPTIND - 1)) 

while (("$#")); do 
    if [[ $1 == -* ]] ; then 
     echo "All opts up front, please." >&2 ; print_help ; exit 2 
    fi 
    echo $1 
    shift 
done 

因爲每一個都是布爾標誌選項,所以你不需要(實際上也不需要)參數,所以我們擺脫了冒號。這些字符都不在IFS中,因此我們不需要用引號包裝它,它將成爲getopts的一個標記。

接下來,我們改變了\?到一個?和擺脫*的,因爲*將字面\?匹配之前,我們可能會在規則以及合併成一個默認的匹配。這是一件好事,因爲用-前綴指定的任何選項都應該是一個選項,並且如果用戶指定了一個您不期望的選項,則用戶會期望程序失敗。

getopts將解析第一件不是參數,並將OPTIND設置爲該位置的值。在這種情況下,我們會將OPTIND - 1(因爲opts是0-索引)轉移到前面。然後,我們會通過將這些參數移開,回顯它們或者如果它們以-開頭而失敗。

,並測試:

[getopts]$ ./go 
OPTIND: 1 
0 
[getopts]$ ./go -t -v go go 
OPTIND: 3 
4 
go 
go 
[getopts]$ ./go -d -v go go 
./go: illegal option -- d 
Usage 
[getopts]$ ./go -t go -v go -d 
OPTIND: 2 
5 
go 
All opts up front, please. 
Usage 
1

v:t:r:s:c:應該是基於您發佈的腳本雙引號

"v:t:r:s:c:" 

,也許你並不需要所有的冒號:

而且你不需要*)

+0

謝謝,有沒有什麼方法可以匹配'非參數',例如「./script asdf」? – AoeAoe 2012-03-21 12:35:38

+0

我不知道我的頭頂。你是否使用更新後的腳本來嘗試它? – 2012-03-21 12:42:18

+0

當getopts返回時,OPTIND被設置爲第一個非選項參數的索引。 – 2012-03-21 12:46:50

1

你需要的,如果要啓用?匹配無效選項提供的getopts的選項字符串後面緊跟一個冒號 - :vtrsc。你也不必以前?

2

反斜槓嘗試以下解決方法:

# Parse the arguments. 
while getopts ':h?f:' opts; do 
    case ${opts} in 

    f) # Foo argument. 
     ;; 

    # My other arguments. 

    \? | h | *) # Prints help. 
     grep " .)\ #" $0 
     exit 0 
     ;; 
    esac 
done 

所以基本上-?/-h將打印參數與基於自身的源代碼註釋。在選項之前指定:也會打印任何其他未知參數的幫助。

+0

不錯的利用grep。通過編寫打印幫助功能節省時間。我確實需要添加「h \?」到arg列表以避免'非法選項'輸出。 – 2016-01-27 16:37:45