2014-10-17 29 views
6

使用getopt分析命令行參數時,可以在選項標記和所需參數的參數之間插入一個空格,但不能插入可選參數。可選參數只有在選項後面纔會被解析。爲什麼不能使用getopt在選項和可選參數之間有空格?

TEMP=`getopt -o p:q:: -n 'mkqueue.sh' -- "[email protected]"` 

if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi 

# Note the quotes around `$TEMP': they are essential! 
eval set -- "$TEMP" 

# Now go through all the options 
while true ; do 
    case "$1" in 
     -p) echo "Option p, argument \`$2'" ; shift 2 ;; 
     -q) 
      case "$2" in 
       "") echo "Option q, no argument"; shift 2 ;; 
       *) echo "Option q, argument \`$2'" ; shift 2 ;; 
      esac ;; 
     --) shift ; break ;; 
     *) echo "Internal error!" ; exit 1 ;; 
    esac 
done 

(在此基礎上:http://software.frodo.looijaard.name/getopt/docs/getopt-parse.bash

當我運行該腳本沒有它的工作原理的可選參數:

./mkqueue.sh -p adfsa -q 
Option p, argument `adfsa' 
Option q, no argument 

如果我嘗試添加可選的參數與以-q它之間的空間不起作用:

./mkqueue.sh -p adfsa -q sdfasdfa 
Option p, argument `adfsa' 
Option q, no argument 

它的作品,如果你沒有作爲儘管所需要的論據適用於空間:

./mkqueue.sh -p adfsa -qsdfasdfa 
Option p, argument `adfsa' 
Option q, argument `sdfasdfa' 

是否有解決方案?

+2

如果它被允許,你會得到另一個問題。假設你的程序也接受一個位置參數。應該將'./a.out -q foo bar'解析爲'./a.out -qfoo bar'還是'./a.out -q - foo bar'? – 5gon12eder 2014-10-17 19:11:59

+1

@ 5gon12eder,如果你有這個答案,你至少會得到我的讚賞。它解釋了「爲什麼」,這是這個問題的標題所要求的。 :) – 2014-10-17 19:41:59

回答

8

即限制在聯機幫助頁記錄爲getopt

一個簡單的短選項是一個' - 」後跟一個短選項字符。如果該選項具有必需的參數,則可以直接在選項字符後面或作爲下一個參數(即在命令行上用空格分隔)寫入該參數。 如果該選項具有可選參數,則必須在選項字符後面直接寫入(如果存在)。

雖然getopt允許「可選的選項參數」,但它們通常被認爲是一個壞主意。 POSIX的Utility Syntax Guidelines,例如,包括:

指南7:選項參數不宜選用。

該指南的基本原因是通過約定,命令行選項的參數可以是任何字符串。例如,它可能看起來像另一種選擇。它可能是文字字符串--,通常表示選項列表的結尾。它可能是一個空字符串。任何東西。

「可選選項參數」的問題在於,只有知道沒有提供可選選項參數的唯一方法是將以下參數識別爲選項或--。但這意味着可選參數的值不能以-開頭。

或者,您也可以選擇由getopt命令行實用程序,這是要求可選參數緊跟選項所採取的解決方案,而無需中間間隔(即在同一個詞是)。但是在這種情況下,可選參數不能是空字符串。

與其創建複雜的規則來解決這些歧義問題,簡單的解決方案 - 由Posix推薦(並且我的權限更少) - 是不允許選項參數是可選的。如果命令行選項有一個共同的值,並且您希望通過不需要鍵入命令來簡化用戶的生活,那麼實現兩個不同的命令行選項,其中一個選項需要參數,另一個選項沒有。常見的技術包括對沒有參數的版本使用小寫字符,對於帶有參數的版本使用相應的大寫字符,或對該版本使用長選項(--option)。

對於那些誰喜歡密集和包裝的說明中,POSIX rationale解釋說:

指南7允許任何字符串是一個選項參數;選項參數可以以任何字符開頭,可以是---,並且可以是空字符串。例如,命令pr -h -pr -h --pr -h -dpr -h +2,和pr -h '',分別----d+2,和一個空字符串包含選項參數。相反,命令pr -h -- -d將-d作爲選項,而不是作爲參數,因爲--是此處的選項參數,而非分隔符。

+0

這是一個很好的解釋,並完成,但我覺得有點密集。打開基本原理的例子可能會有所幫助(不是每個人都知道' - '的意思,f'rinstance)。 – 2014-10-17 20:10:29

相關問題