Quando você escreve o bit de análise do seu código na linha de comando, você especifica quais opções aceitam argumentos e quais não. Por exemplo, em um script de shell aceitando uma opção -h
(para ajuda, por exemplo) e uma opção -a
que deve receber um argumento, você faz
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
bit diz "Estou esperando analisar duas opções, -a
e -h
e -a
devem receber um argumento" (é o :
após a
que informa ao analisador que -a
leva um argumento).
Portanto, nunca há qualquer ambigüidade em onde uma opção termina, onde seu valor é iniciado 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 você na maioria das vezes 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 pára na primeira não opção, então quando você tem coisas na linha de comando que parece como 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 isso:
$ bash test.sh -a hello -- -world
h: 0
a: hello
O --
sinaliza um fim de opções de linha de comando e o -world
bit é deixado para o programa fazer o que quiser com (está em uma das variáveis posicionais).
Ou seja, como você remove um arquivo que tem um traço no início do nome do arquivo com rm
.
EDITAR :
Utilitários escritos em C chamam getopt()
(declarado em unistd.h
), que funciona basicamente da mesma maneira. De fato, para todos nós sabemos, a bash
function getopts
pode ser implementada usando uma chamada para a função da biblioteca C getopt()
. Perl, Python e outras linguagens têm bibliotecas similares de análise de linha de comando, e é mais provável que elas realizem sua análise de maneira similar.
Algumas dessas rotinas de biblioteca getopt
e getopt
-like também lidam com opções "longas". Estes são geralmente precedidos por traço duplo ( --
), e as opções longas que recebem argumentos geralmente o fazem após um sinal de igual, por exemplo a opção --block-size=SIZE
de [algumas implementações] do du
utility (que também permite que -B SIZE
especifique a mesma coisa).
Os manuais de motivos são frequentemente escritos para mostrar um espaço entre as opções curtas e seus argumentos são provavelmente para legibilidade.
EDITAR : Realmente as ferramentas antigas, como os utilitários dd
e tar
, têm opções sem traços na frente delas. Isso é puramente por razões históricas e por manter compatibilidade com software que depende deles para trabalhar exatamente dessa maneira. O utilitário tar
ganhou a capacidade de escolher opções com traços em tempos mais recentes. O manual do BSD para tar
chama as opções antigas para "flags empacotados".