Eu quero chamar o myscript
arquivo desta maneira:
$ ./myscript -s 45 -p any_string
ou
$ ./myscript -h #should display help
$ ./myscript #should display help
Meus requisitos são:
getopt
aqui para obter os argumentos de entrada- verifique se
-s
existe, se não retornar um erro - verifique se o valor após
-s
é 45 ou 90 - verifique se
-p
existe e existe uma sequência de entrada após - se o usuário entrar
./myscript -h
ou./myscript
então exibir ajuda
Eu tentei até agora este código:
#!/bin/bash
while getopts "h:s:" arg; do
case $arg in
h)
echo "usage"
;;
s)
strength=$OPTARG
echo $strength
;;
esac
done
Mas com esse código eu recebo erros. Como fazer isso com o Bash e getopt
?
-s
, torná-lo um argumento posicional:./myscript 45 anystring
.$./myscript -s 45 -p any_string
-p
for realmente uma opção (ou seja, seu programa poderá prosseguir se não estiver presente). Nesse caso./myscript 45 -p any_string
,. (Acho quegetopt
pode lidar com opções variadas e argumentos posicionais, enquanto obash
comando internogetopts
exige que todos os argumentos posicionais para ser colocado após opções.)Respostas:
Exemplo é executado:
fonte
usage()
Realmente deve retornar 1?-h
ele deve retornar0
, ao pressionar um sinalizador inexistente, ele deve retornar>0
(por uma questão de simplicidade, não diferenciei esses casos e ninguém o obriga a imprimir o texto de uso no último caso) . Eu já vi programas que sempre retornam!= 0
, mesmo depois-h/--help
. Talvez eu deva atualizar o trecho caso as pessoas usem isso como clichê (espero que não)?getopts
') design, não existe "argumentos opcionais" comgetopts
. O analisador simplesmente não pode saber se o próximo token é um argumento para a opção atual ou uma opção por si só, pois-p
pode ser o valor pretendido. Você pode resolver isso se souber absolutamente que um parâmetro de opção não pode se parecer com outra opção válida, sim, mas pode-se dizer que há uma razão pela qual argumentos opcionais não estão definidos no POSIX.bash
lexer a identificar variáveis. Em muitos casos, eles são desnecessários e o fato de eu sempre usá-los é apenas uma questão de estilo de codificação pessoal. Para mim, é mais fácil (e mais bonito) sempre usá-los sempre, em vez de lembrar as regras de análise em relação à ambiguidade. Praticamente o mesmo por que alguém escreveria emif (foo) { bar; }
vez de usarif (foo) bar;
uma linguagem no estilo C (estética e / ou evitar erros tolos).O problema com o código original é o seguinte:
h:
espera o parâmetro onde não deveria, então mude para apenash
(sem dois pontos)-p any_string
, você precisa adicionarp:
à lista de argumentosBasicamente,
:
após a opção significa que requer o argumento.A sintaxe básica de
getopts
é (consulteman bash
:):Onde:
OPTSTRING
é string com lista de argumentos esperados,h
- verifique a opção-h
sem parâmetros; dá erro em opções não suportadas;h:
- verifique a opção-h
com o parâmetro; dá erros em opções não suportadas;abc
- Verifique se há opções-a
,-b
,-c
; dá erros em opções não suportadas;:abc
- Verifique se há opções-a
,-b
,-c
; silencia erros em opções não suportadas;Notas: Em outras palavras, dois pontos na frente das opções permitem lidar com os erros no seu código. A variável conterá
?
no caso de opção não suportada,:
no caso de valor ausente.OPTARG
- está definido como o valor atual do argumento,OPTERR
- indica se o Bash deve exibir mensagens de erro.Portanto, o código pode ser:
Exemplo de uso:
Veja: Tutorial de pequenas getopts no Bash Hackers Wiki
fonte
usage() { echo "$0 usage:" && grep "[[:space:]].)\ #" $0 | sed 's/#//' | sed -r 's/([a-z])\)/-\1/'; exit 0; }
. Ele considera apenas um caractere de espaço em branco antes da opção de letra, remove o # do comentário e coloca um '-' antes da opção de letra, tornando-o mais claro para o comando.:
acertar até que eu vi essas anotações. Precisamos adicionar:
a às opções em que estamos esperando um argumento.Usar
getopt
Por que obter?
Analisar argumentos de linha de comando elaborados para evitar confusão e esclarecer as opções que estamos analisando para que o leitor dos comandos possa entender o que está acontecendo.
O que é getopt?
getopt
é usado para dividir (analisar) opções nas linhas de comando para facilitar a análise por procedimentos de shell e verificar opções legais. Ele usa asgetopt(3)
rotinas GNU para fazer isso.getopt
pode ter os seguintes tipos de opções.Nota: Neste documento, durante a explicação da sintaxe:
COMO USAR
getopt
?Sintaxe: Primeira Forma
Exemplos:
Aqui h, v, t são as opções e -h -v -t é como as opções devem ser dadas na linha de comando.
No parâmetro opcional, o valor não pode ter espaço em branco com a opção Portanto, no exemplo "-t123", -t é a opção 123 é o valor.
Sintaxe: Segunda Forma
Aqui, depois que o getopt é dividido em cinco partes
Exemplos
Sintaxe: Terceira Forma
Aqui, depois que o getopt é dividido em cinco partes
Exemplos
GETOPT_OPTIONS
getopt_options altera a maneira como os parâmetros de linha de comando são analisados.
Abaixo estão algumas das getopt_options
Opção: -l ou --longoptions
Por exemplo,
--name=Karthik
é uma opção longa enviada na linha de comando. Em getopt, o uso de opções longas é comoComo name: é especificado, a opção deve conter um valor
Opção: -a ou --alternative
Exemplo, em vez de
--name=Karthik
você poderia usar apenas-name=Karthik
Um exemplo completo de script com o código:
Executando este arquivo de script:
fonte
O exemplo empacotado com
getopt
(minha distribuição o colocou/usr/share/getopt/getopt-parse.bash
) parece que abrange todos os seus casos:fonte
Sei que isso já foi respondido, mas para o registro e para qualquer pessoa com os mesmos requisitos que eu, decidi postar essa resposta relacionada. O código é inundado com comentários para explicar o código.
Resposta atualizada:
Salve o arquivo como
getopt.sh
:Então você pode usá-lo assim:
Resposta antiga:
Recentemente, eu precisava usar uma abordagem genérica. Me deparei com esta solução:
Eu não testei isso mais ou menos, então eu poderia ter alguns bugs lá.
fonte
getopts
uma função, adicione-local OPTIND OPTARG
a à funçãogetopts
Exemplo POSIX 7
Também vale a pena conferir o exemplo do padrão: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/getopts.html
E então podemos experimentar:
Testado no Ubuntu 17.10,
sh
é o traço 0.5.8.fonte
"getops" e "getopt" são muito limitados. Embora "getopt" seja sugerido para não ser usado, ele oferece opções longas. Onde "getopts" permite apenas opções de caracteres únicos, como "-a" "-b". Existem mais algumas desvantagens ao usar qualquer um deles.
Então, eu escrevi um pequeno script que substitui "getopts" e "getopt". É um começo, provavelmente poderia ser melhorado bastante.
Atualização 08-04-2020 : adicionei suporte para hífens, por exemplo, "--package-name".
fonte