Ao escrever a linha de comando que analisa parte do seu código, você especifica quais opções recebem argumentos e quais não. Por exemplo, em um script de shell que aceita uma -h
opção (para obter ajuda, por exemplo) e uma -a
opção que deve receber um argumento, você deve
opt_h=0 # default value
opt_a=""
while getopts 'a:h' opt; do
case $opt in
h) opt_h=1 ;;
a) opt_a="$OPTARG" ;;
esac
done
echo "h: $opt_h"
echo "a: $opt_a"
O a:h
trecho diz "Estou esperando analisar duas opções -a
e -h
, e -a
deve aceitar um argumento" (é o :
seguinte a
que diz ao analisador que -a
aceita um argumento).
Portanto, nunca há ambiguidade em onde uma opção termina, onde seu valor começa e onde outra começa depois disso.
Executando:
$ bash test.sh -h -a hello
h: 1
a: hello
$ bash test.sh -h -ahello
h: 1
a: hello
$ bash test.sh -hahello
h: 1
a: hello
É por isso que na maioria das vezes você não deve escrever seu próprio analisador de linha de comando para analisar as opções.
Há apenas um caso neste exemplo que é complicado. A análise geralmente para na primeira não opção, portanto, quando você tem coisas na linha de comando que se parecem com opções:
$ bash test.sh -a hello -world
test.sh: illegal option -- w
test.sh: illegal option -- o
test.sh: illegal option -- r
test.sh: illegal option -- l
test.sh: illegal option -- d
h: 0
a: hello
O seguinte resolve que:
$ bash test.sh -a hello -- -world
h: 0
a: hello
Ele --
sinaliza as opções de final de linha de comando e o -world
bit é deixado para o programa fazer o que quiser (está em uma das variáveis posicionais).
A propósito, é assim que você remove um arquivo com um traço no início de seu nome de arquivo rm
.
EDIT :
Os utilitários escritos em C chamam getopt()
(declarados em unistd.h
) que funcionam praticamente da mesma maneira. Na verdade, por tudo que sabemos, a bash
função getopts
pode ser implementado usando uma chamada para a função de biblioteca C getopt()
. Perl, Python e outras linguagens têm bibliotecas de análise de linha de comando semelhantes e é mais provável que elas realizem sua análise de maneiras semelhantes.
Algumas dessas rotinas de biblioteca getopt
e getopt
similares também lidam com opções "longas". Geralmente, são precedidos por double-dash ( --
), e as opções longas que recebem argumentos geralmente o fazem após um sinal de igual, por exemplo, a --block-size=SIZE
opção de [algumas implementações do] du
utilitário (que também permite -B SIZE
especificar a mesma coisa).
Os manuais de razão são muitas vezes escritos para mostrar um espaço entre as opções curtas e seus argumentos provavelmente para facilitar a leitura.
EDIT : Ferramentas realmente antigas, como os utilitários dd
e tar
, têm opções sem traços na frente deles. Isso é puramente por razões históricas e para manter a compatibilidade com o software que depende deles para funcionar exatamente dessa maneira. O tar
utilitário ganhou a capacidade de escolher opções com traços nos últimos tempos. O manual do BSD tar
chama as opções de estilo antigo para "sinalizadores agrupados".