2014-10-17 10 views
6

Quando si utilizza getopt per analizzare i parametri della riga di comando, è possibile inserire uno spazio tra il flag di opzione e l'argomento per gli argomenti richiesti ma non per gli argomenti facoltativi. Gli argomenti facoltativi verranno analizzati solo se sono corretti dopo l'opzione.Perché non posso avere uno spazio tra l'opzione e l'argomento opzionale usando 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 

(Sulla base di questo: http://software.frodo.looijaard.name/getopt/docs/getopt-parse.bash)

Quando eseguo lo script senza l'argomento opzionale funziona:

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

Se provo ad aggiungere l'argomento opzionale per -q con un spazio nel mezzo non funziona:

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

Funziona se non si dispone di passo tra l'opzione e l'argomento, anche se gli argomenti necessari funzionano con lo spazio:

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

C'è una soluzione per questo?

+2

Se fosse permesso, avresti un altro problema. Supponiamo che il tuo programma accetti anche un argomento posizionale. Dovremmo './a.out -q foo bar' essere analizzato come' ./a.out -qfoo bar' o come './a.out -q - foo bar'? – 5gon12eder

+1

@ 5gon12eder, se tu avessi quello come risposta, avresti almeno il mio upvote. Spiega il "perché", che è quello che chiede il titolo di questa domanda. :) –

risposta

8

Tale limitazione è documentato nella pagina di manuale di getopt:

Una semplice opzione breve è un `-' seguito da un breve carattere di opzione. Se l'opzione ha un argomento obbligatorio, può essere scritta direttamente dopo il carattere dell'opzione o come parametro successivo (cioè separato da spazi bianchi sulla riga di comando). Se l'opzione ha un argomento facoltativo, deve essere scritto direttamente dopo il carattere dell'opzione, se presente.

Anche se getopt permette "gli argomenti delle opzioni facoltative", che sono generalmente considerati di essere una cattiva idea. Il Posix Utility Syntax Guidelines, per esempio, includono:

Orientamento 7: Opzione-argomenti non dovrebbero essere facoltativo.

Il motivo di base di questa linea guida è che per convenzione l'argomento di un'opzione della riga di comando può essere una qualsiasi stringa. Ad esempio potrebbe sembrare un'altra opzione. Potrebbe essere la stringa letterale --, che normalmente indica la fine dell'elenco di opzioni. Potrebbe essere una stringa vuota. Nulla.

Il problema con "argomenti di opzione facoltativi" è che l'unico modo per sapere che un argomento di opzione facoltativo non è fornito è riconoscere il seguente argomento come un'opzione o --. Ma ciò significa che il valore dell'argomento facoltativo non può iniziare con un -.

In alternativa, è possibile scegliere la soluzione adottata dall'utilità della riga di comando getopt, che richiede che l'argomento facoltativo segua immediatamente l'opzione, senza uno spazio intermedio (ovvero, si trova nella stessa parola). Ma in questo caso, l'argomento facoltativo non può essere una stringa vuota.

Piuttosto che creare complicate regole per risolvere queste ambiguità, la soluzione semplice - raccomandata da Posix (e, con molta meno autorità, da parte mia) - è quella di non permettere che gli argomenti delle opzioni siano opzionali.Se esiste un valore comune per un'opzione della riga di comando e si desidera semplificare la vita dell'utente non richiedendone la digitazione, implementare due diverse opzioni della riga di comando, una delle quali accetta un argomento e l'altra di cui non lo fa. Le tecniche comuni includono l'uso di un carattere minuscolo per la versione senza argomento e il carattere maiuscolo corrispondente per la versione con un argomento o l'utilizzo di un'opzione lunga (--option) per quella versione.

Per chi preferisce una spiegazione denso e ricco, il Posix rationale spiega che:

Orientamento 7 permette qualsiasi stringa di essere un'opzione-argomento; un argomento opzione può iniziare con qualsiasi carattere, può essere - o -- e può essere una stringa vuota. Ad esempio, i comandi pr -h -, pr -h --, pr -h -d, pr -h +2, e pr -h '' contengono l'opzione-argomenti -, --, -d, +2, e una stringa vuota, rispettivamente. Al contrario, il comando pr -h -- -d considera -d come opzione, non come argomento, poiché lo -- è un argomento di opzione qui, non un delimitatore.

+0

È una buona spiegazione e completa, ma penso che sia un po 'denso. Disimballare un po 'gli esempi del razionale potrebbe essere utile (non tutti sanno cosa '--' significa, per istanza). –

Problemi correlati