2012-10-31 19 views
0

我想寫一個腳本,需要-c-f其中每個都需要一個選項。爲什麼這些參數解析錯誤?

當我運行我的腳本下面我得到一些意外的錯誤:

$ ./user.sh -c 
./user.sh: option requires an argument -- c 

Usage: user.sh -c username -f filename 
    -c username 
    -f SSH public key 

$ ./user.sh -c gg 
Error: You have not given a filename. 

在第一種情況下,我也喜歡它說我缺少的選項-c而在第二種情況下我也喜歡它說我缺少-f

問題

我怎麼做出這樣的錯誤處理,而我在做什麼錯?

user.sh

#!/bin/bash                        

usage() { 
    echo "Usage: user.sh -c username -f filename" 
    echo " -c username" 
    echo " -f SSH public key" 
    echo "" 
} 

if ! [ "$*" ]; then 
    usage 
    exit 1 
fi 

while getopts "c:f:" opt; do 
    case $opt in 
     c) user=$OPTARG;; 
     f) filename=$OPTARG;; 
     \?) 
      echo 
      usage 
      exit 1;; 
     *) echo "Internal error: Unknown option.";; 
    esac 
done 

if ! [ $filename ]; then 
    echo "Error: You have not given a filename." 
    exit 1 
fi 

if ! [ $user ]; then 
    echo "Error: You have not given an username." 
    exit 1 
fi 

回答

3

c:則說,-c選項必須跟用戶名「。

錯誤消息顯示'-c選項後面沒有用戶名'。

當然,它沒有提到'用戶名',但這是因爲它不知道它是什麼,它遵循選項-c

內置的getopts無法處理強制性選項;您必須通過檢查強制選項是否已通過,爲自己編寫代碼。如果同一選項被指定兩次,也不用擔心;你的代碼必須處理,如果它很重要。 (很容易讓最後指定的值生效。)

現代風格是爲了避免強制參數前的選項字母。我並不完全贊成這種改變。這意味着參數的排序變得至關重要,因爲使用選項字母來表示後面沒有的參數。如果沒有選項字母,你會寫:./user.sh username filename,但選項字母,您可以一次將這些和期望它的工作:

./user.sh -c username -f filename 
./user.sh -f filename -c username 

注意,責任是你不用擔心額外的參數了。您通常會使用:

shift $(($OPTIND - 1)) 

刪除處理參數,那麼你可以做:就這一主題

case "$#" in 
(0) : No extra arguments - OK;; 
(*) echo "$0: Too many arguments" >&2; exit 1;; 
esac 

和變化。請注意,錯誤報告被髮送到標準錯誤,而不是標準輸出 - >&2重定向將標準輸出(文件描述符1)發送到標準錯誤(文件描述符2)。集體

usage() 
{ 
    { 
    echo "Usage: user.sh -c username -f filename" 
    echo " -c username Name of user to connect as" 
    echo " -f filename SSH public key file" 
    echo "" 
    } >&2 
} 

內括號做I/O重定向,而無需啓動一個子shell:

爲了避免混淆,我會有點不同編碼的使用功能。當你需要發送一些echo命令到同一個地方時,這會很有用。我還以不同的方式呈現了詳細信息,以便用戶不會認爲'SSH公鑰'是遵循-f的三個參數。如果有任何純粹的選項標誌,他們會跟着空格:

echo " -V    Print version information and exit" 
+0

非常感謝。你知道編寫'--help'輸出的標準嗎?例如。我應該擁有多少空間,並指出強制性和可選參數和選項? –

+1

在摘要行中,可選項目放在方括號中,強制不是:'cmd [-ov] -c username -f filename'。沒有足夠的空間標準。在這個例子中,我用了4;這是足夠的; 2可能是分離的最小值。否則,請瀏覽...使用'--help'運行各種命令並查看它們的功能。有些比其他人長。 –

相關問題