Desejo que formas longas e curtas de opções de linha de comando sejam chamadas usando meu script de shell.
Eu sei que isso getopts
pode ser usado, mas, como no Perl, não fui capaz de fazer o mesmo com o shell.
Alguma idéia de como isso pode ser feito, para que eu possa usar opções como:
./shell.sh --copyfile abc.pl /tmp/
./shell.sh -c abc.pl /tmp/
Acima, os dois comandos significam a mesma coisa para o meu shell, mas getopts
, usando , não fui capaz de implementá-los?
bash
command-line-arguments
getopt
getopts
gagneet
fonte
fonte
Respostas:
Há três implementações que podem ser consideradas:
Bash builtin
getopts
. Isso não suporta nomes longos de opções com o prefixo de traço duplo. Ele suporta apenas opções de um caractere.Implementação do BSD UNIX do
getopt
comando independente (que é o que o MacOS usa). Isso também não oferece opções longas.Implementação GNU de autônomo
getopt
. O GNUgetopt(3)
(usado pela linha de comandogetopt(1)
no Linux) suporta a análise de opções longas.Algumas outras respostas mostram uma solução para usar o bash embutido
getopts
para imitar opções longas. Essa solução, na verdade, faz uma pequena opção cujo caractere é "-". Então você recebe "-" como a bandeira. Em seguida, qualquer coisa a seguir que se torne OPTARG e você teste o OPTARG com um aninhadocase
.Isso é inteligente, mas vem com advertências:
getopts
não pode aplicar a especificação de opção. Não pode retornar erros se o usuário fornecer uma opção inválida. Você precisa fazer sua própria verificação de erro ao analisar o OPTARG.Portanto, embora seja possível escrever mais código para solucionar a falta de suporte para opções longas, isso é muito mais trabalhoso e derrota parcialmente o propósito de usar um analisador getopt para simplificar seu código.
fonte
getopt
egetopts
são bestas diferentes, e as pessoas parecem ter um pouco de mal-entendido do que fazem.getopts
é um comando interno parabash
processar opções de linha de comando em um loop e atribuir cada opção e valor encontrado, por sua vez, a variáveis internas, para que você possa processá-las ainda mais.getopt
, no entanto, é um programa utilitário externo e, na verdade, não processa suas opções para você da maneira que, por exemplogetopts
, o bash , oGetopt
módulo Perl ou o Pythonoptparse
/argparse
modules. Tudo o quegetopt
faz é canonizar as opções passadas - ou seja, convertê-las para um formato mais padrão, para que seja mais fácil para um script de shell processá-las. Por exemplo, um aplicativo degetopt
pode converter o seguinte:nisso:
Você precisa fazer o processamento real sozinho. Você não precisa usar
getopt
-lo se fizer várias restrições na maneira de especificar opções:-o
acima), o valor deve ser apresentado como um argumento separado (após um espaço).Por que usar em
getopt
vez degetopts
? O motivo básico é que apenas o GNUgetopt
oferece suporte para opções de linha de comando com nomes longos. 1 (GNUgetopt
é o padrão no Linux. O Mac OS X e o FreeBSD vêm com uma funcionalidade básica e não muito útilgetopt
, mas a versão do GNU pode ser instalada; veja abaixo.)Por exemplo, aqui está um exemplo de uso do GNU
getopt
, de um script meu chamadojavawrap
:Isso permite especificar opções como
--verbose -dm4096 --minh=20 --maxhe 40 --debugfi="/Users/John Johnson/debug.txt"
ou semelhante. O efeito da chamada paragetopt
é canonizar as opções para--verbose -d -m 4096 --minheap 20 --maxheap 40 --debugfile "/Users/John Johnson/debug.txt"
que você possa processá-las mais facilmente. A citação ao redor"$1"
e"$2"
é importante, pois garante que os argumentos com espaços sejam tratados adequadamente.Se você excluir as 9 primeiras linhas (tudo na
eval set
linha), o código ainda funcionará ! No entanto, seu código será muito mais exigente em quais tipos de opções ele aceita: Em particular, você precisará especificar todas as opções no formulário "canônico" descrito acima. Com o uso degetopt
, no entanto, você pode opções único grupo letras, usar mais curtos formas não ambíguas de longas-opções, utilize o--file foo.txt
ou--file=foo.txt
estilo, utilize o-m 4096
ou-m4096
estilo, misturar opções e não-opções em qualquer ordem, etc.getopt
também gera uma mensagem de erro se forem encontradas opções não reconhecidas ou ambíguas.NOTA : Na verdade, existem duas versões totalmente diferentes
getopt
, básicagetopt
e GNUgetopt
, com recursos diferentes e convenções de chamada diferentes. 2 O Basicgetopt
está bastante quebrado: ele não apenas lida com opções longas, como também não consegue lidar com espaços incorporados dentro de argumentos ou argumentos vazios, enquantogetopts
faz isso corretamente. O código acima não funcionará no básicogetopt
. O GNUgetopt
é instalado por padrão no Linux, mas no Mac OS X e FreeBSD ele precisa ser instalado separadamente. No Mac OS X, instale o MacPorts ( http://www.macports.org ) e, em seguida,sudo port install getopt
instale o GNUgetopt
(geralmente no . No FreeBSD, instale ./opt/local/bin
), e verifique se/opt/local/bin
está no caminho do shell antes de/usr/bin
misc/getopt
Um guia rápido para modificar o código de exemplo para o seu próprio programa: Das primeiras linhas, tudo é "padrão" que deve permanecer o mesmo, exceto a linha que chama
getopt
. Você deve alterar o nome do programa depois-n
, especificar opções curtas depois-o
e opções longas depois--long
. Coloque dois pontos depois das opções que levam um valor.Finalmente, se você vir um código que acabou de ser
set
substituídoeval set
, ele foi escrito para o BSDgetopt
. Você deve alterá-lo para usar oeval set
estilo, que funciona bem com as duas versõesgetopt
, enquanto o plainset
não funciona corretamente com o GNUgetopt
.1 Na verdade,
getopts
inksh93
suporta opções de nomes longos, mas esse shell não é usado com tanta frequência quantobash
. Emzsh
, usezparseopts
para obter essa funcionalidade.2 Tecnicamente, "GNU
getopt
" é um nome impróprio; esta versão foi realmente escrita para Linux e não para o projeto GNU. No entanto, segue todas as convenções do GNU, e o termo "GNUgetopt
" é comumente usado (por exemplo, no FreeBSD).fonte
getopt
no Linux não é um utilitário GNU e o tradicionalgetopt
não vem inicialmente do BSD, mas do AT&T Unix. O ksh93getopts
(também da AT&T) suporta opções longas no estilo GNU.POSIXLY_CORRECT
), enquanto "getopt aprimorado pelo Linux" sugere erroneamente que esta versão existe apenas em Linux.getopt
pode ser facilmente transportado para outros Unices, mas muitos outros softwaresutil-linux
são específicos do Linux). Todos os programas não-GNU que usam o GNU getopt (3) entendem$POSIX_CORRECT
. Por exemplo, você não diria queaplay
é o GNU apenas por esses motivos. Eu suspeito que quando o FreeBSD menciona o GNU getopt, eles significam a API C do GNU getopt (3).getopt
utilitário, não getopt (3).A função getopts interna do Bash pode ser usada para analisar opções longas, colocando um caractere de traço seguido de dois pontos no optspec:
Após copiar para o nome do arquivo executável =
getopts_test.sh
no diretório de trabalho atual , é possível produzir uma saída comoObviamente, getopts não realiza
OPTERR
verificação nem análise de argumento de opção para as opções longas. O fragmento de script acima mostra como isso pode ser feito manualmente. O princípio básico também funciona no shell Debian Almquist ("traço"). Observe o caso especial:Observe que, como aponta o GreyCat em http://mywiki.wooledge.org/BashFAQ , esse truque explora um comportamento não-padrão do shell que permite o argumento da opção (ou seja, o nome do arquivo em "-f filename") para ser concatenado com a opção (como em "-ffilename"). O padrão POSIX diz que deve haver um espaço entre eles, que no caso de "- longoption" encerraria a análise de opções e transformaria todas as longoptions em argumentos que não são de opções.
fonte
!
inval="${!OPTIND}
?getopts
automaticamente apenas incrementaOPTIND
com 1, mas, no nosso caso, precisamos incrementar em 2; portanto, incrementamos manualmente em 1 e, em seguida,getopts
aumentamos em 1 novamente para nós automaticamente.$
necessárias.OPTIND=$(( $OPTIND + 1 ))
pode ser justoOPTIND=$(( OPTIND + 1 ))
. Ainda mais interessante, você pode até atribuir e aumentar variáveis dentro de uma expressão aritmética, para que seja possível abreviá-la ainda mais: $(( ++OPTIND ))
, ou mesmo(( ++OPTIND ))
levar em conta que++OPTIND
sempre será positivo, para que não desarme um shell executado com o-e
opção :-) gnu.org/software/bash/manual/html_node/Shell-Arithmetic.html--very-bad
dá um aviso?O
getopts
comando interno ainda é, AFAIK, limitado apenas às opções de caractere único.Existe (ou costumava ser) um programa externo
getopt
que reorganizava um conjunto de opções para facilitar a análise. Você pode adaptar esse design para lidar com opções longas também. Exemplo de uso:Você pode usar um esquema semelhante com um
getoptlong
comando.Observe que a fraqueza fundamental do
getopt
programa externo é a dificuldade de lidar com argumentos com espaços neles e em preservar esses espaços com precisão. É por isso que o built-ingetopts
é superior, embora limitado pelo fato de lidar apenas com opções de letra única.fonte
eval set
entre aspas (veja minha resposta abaixo) para que ele também funcione corretamente com o GNU getopt (o padrão no Linux) e lide com os espaços corretamente.${1+"$@"}
é singular e está em desacordo com o que é necessário nos shells modernos e especificamente com qualquer shell que você encontraria no Linux. Consulte Usando $ 1: + "$ @"} em / bin / sh para obter uma discussão dessa notação.)eval set
faz a coisa certa com o GNU e o BSDgetopt
, enquanto o simplesset
apenas faz a coisa certa com o BSDgetopt
. Portanto, você também podeeval set
incentivar as pessoas a adquirir o hábito de fazer isso. Entre, obrigado, eu não sabia que${1+"$@"}
não era mais necessário. Preciso escrever coisas que funcionem tanto no Mac OS X quanto no Linux - entre as duas, elas forçam muita portabilidade. Acabei de verificar e"$@"
, de fato, fazer a coisa certa em todossh
,bash
,ksh
, ezsh
no Mac OS X; certamente no Linux também.Aqui está um exemplo que realmente usa getopt com opções longas:
fonte
eval set
entre aspas (veja minha resposta abaixo) para que ele também funcione corretamente com o GNU getopt (o padrão no Linux) e lide com os espaços corretamente.getopt
enquanto a pergunta é sobre o assuntogetopts
.(--
,(-*
e(*
padrões válidos? Como eles são diferentes de--
,-*
e*
?(--)
é idêntico a--)
umacase
estrofe. É estranho ver a indentação desigual e o uso inconsistente desse parênteses principal opcional, mas o código atual da resposta parece válido para mim.Opções longas podem ser analisadas pelo padrão
getopts
incorporado como "argumentos" para a-
"opção"Este é um shell POSIX portátil e nativo - nenhum programa ou bashisms externo é necessário.
Este guia implementa opções longas como argumentos para a
-
opção, portanto,--alpha
é vistogetopts
como-
com argumentoalpha
e--bravo=foo
como-
argumentobravo=foo
. O verdadeiro argumento pode ser colhida com uma substituição simples:${OPTARG#*=}
.Neste exemplo,
-b
e-c
(e suas formas longas,--bravo
e--charlie
) têm argumentos obrigatórios. Os argumentos para opções longas vêm após sinais de igual, por exemplo--bravo=foo
(delimitadores de espaço para opções longas seria difícil de implementar, veja abaixo).Como isso usa o
getopts
built-in , essa solução suporta o uso de comocmd --bravo=foo -ac FILE
(que combinou opções-a
e-c
intercala opções longas com opções padrão), enquanto a maioria das outras respostas aqui se esforçam ou deixam de fazer isso.Quando a opção é um hífen (
-
), é uma opção longa.getopts
terá analisado a opção longa real em$OPTARG
, por exemplo,--bravo=foo
originalmente defineOPT='-'
eOPTARG='bravo=foo'
. Aif
estrofe define$OPT
o conteúdo de$OPTARG
antes do primeiro sinal de igual (bravo
no nosso exemplo) e depois remove o mesmo do início de$OPTARG
(produzindo=foo
nesta etapa, ou uma sequência vazia, se não houver=
). Finalmente, retiramos a liderança do argumento=
. Neste ponto,$OPT
existe uma opção curta (um caractere) ou uma opção longa (2 ou mais caracteres).O
case
então corresponde às opções curtas ou longas. Para opções curtas,getopts
reclama automaticamente sobre opções e argumentos ausentes, portanto, temos que replicá-los manualmente usando aneeds_arg
função, que sai fatalmente quando$OPTARG
está vazia. A??*
condição corresponderá a qualquer opção longa restante (?
corresponde a um único caractere e*
corresponde a zero ou mais, portanto,??*
corresponde a 2 ou mais caracteres), permitindo emitir o erro "Opção ilegal" antes de sair.(Uma observação sobre nomes de variáveis com letras maiúsculas: geralmente, o conselho é reservar variáveis com letras maiúsculas para uso do sistema. Estou mantendo
$OPT
como letras maiúsculas para mantê-las alinhadas$OPTARG
, mas isso quebra essa convenção. se encaixa porque isso é algo que o sistema deveria ter feito e deve ser seguro porque não há padrões (afaik) que usem essa variável.)Para reclamar de argumentos inesperados para opções longas, imite o que fizemos para argumentos obrigatórios: use uma função auxiliar. Basta virar o teste para reclamar de um argumento quando não se espera:
Uma versão mais antiga desta resposta tentou aceitar opções longas com argumentos delimitados por espaço, mas não era confiável;
getopts
poderia terminar prematuramente com a suposição de que o argumento estava além de seu escopo e o incremento manual$OPTIND
não funciona em todos os shells.Isso seria realizado usando uma destas técnicas:
eval "bravo=\"\$$OPTIND\""
bravo="${!OPTIND}"
P
bandeira :bravo="${(P)OPTIND}"
e depois concluiu com algo como
[ $# -gt $OPTIND ] && OPTIND=$((OPTIND+1))
fonte
letter-c
não precisa de argumento, não seria suficiente usá-loletter-c)
? o*
parece redundante.getopts
para no primeiro argumento posicional, pois não foi projetado para lidar com eles. Isso permite subcomandos com seus próprios argumentos, por exemplogit diff --color
, então eu interpretariacommand --foo=moo bar --baz waz
como tendo--foo
como argumento paracommand
e--baz waz
como argumento (com opção) para obar
subcomando. Isso pode ser feito com o código acima. Rejeito--bravo -blah
porque--bravo
requer um argumento e não está claro que-blah
não seja outra opção.eval
no shell POSIX, está listado abaixo do restante da resposta.Dê uma olhada no shFlags, que é uma biblioteca shell portátil (ou seja: sh, bash, dash, ksh, zsh no Linux, Solaris, etc.).
Isso torna a adição de novos sinalizadores tão simples quanto adicionar uma linha ao seu script e fornece uma função de uso gerada automaticamente.
Aqui está um simples
Hello, world!
usando shFlag :Para sistemas operacionais que possuem o getopt aprimorado que suporta opções longas (por exemplo, Linux), você pode:
De resto, você deve usar a opção curta:
Adicionar um novo sinalizador é tão simples quanto adicionar um novo
DEFINE_ call
.fonte
Usando
getopts
com opções curtas / longas e argumentosFunciona com todas as combinações, por exemplo:
Algumas declarações para este exemplo
Como seria a função de uso
getops
com sinalizadores longos / curtos, bem como argumentos longosResultado
Combinando o acima em um script coeso
fonte
eval
abordagem de argumentos espaçados em opções longas e achei que não era confiável com certas conchas (embora eu espere que funcione com o bash, caso em que você não precisa usareval
). Veja minha resposta para saber como aceitar argumentos de opção longos=
e minhas tentativas notadas de usar o espaço. Minha solução não faz chamadas externas, enquanto esta é utilizadacut
algumas vezes.Outra maneira ...
fonte
$args
reatribuição? Isso pode até ser feito sem basismos, mas esse código perderá espaço em opções e argumentos (não acho que o$delim
truque funcione). Você pode executarset
dentro dofor
loop se tiver cuidado o suficiente para esvaziá-lo apenas na primeira iteração. Aqui está uma versão mais segura sem bashisms.Eu meio que resolvi assim:
Estou sendo burro ou algo assim?
getopt
egetopts
são tão confusos.fonte
-ltr
ou-lt -r
também-l -t -r
). E também fornece algum tratamento de erro e uma maneira fácil de mudar os parâmetros tratados quando a opção de tratamento é finalizada.Caso você não queira a
getopt
dependência, faça o seguinte:Obviamente, você não pode usar opções de estilo longas com apenas um traço. E se você quiser adicionar versões reduzidas (por exemplo, --verbos em vez de --verbose), precisará adicioná-las manualmente.
Mas se você deseja obter
getopts
funcionalidade juntamente com opções longas, esta é uma maneira simples de fazê-lo.Eu também coloquei esse trecho em uma essência .
fonte
--)
, parece estarshift ;
faltando. No momento,--
ele permanecerá como o primeiro argumento não opcional.--
opção precise de umashift
. Digo isso é melhor porque as alternativas são ou plataforma versões dependentes degetopt
ougetopts_long
ou você tem que forçar-curtas opções para ser usado apenas no início do comando (ou seja - você usagetopts
, em seguida, processar opções muito tempo depois), enquanto esta dá qualquer ordem e controle completo.O built-in
getopts
não pode fazer isso. Existe um programa externo getopt (1) que pode fazer isso, mas você só o obtém no Linux a partir do pacote util-linux . Ele vem com um script de exemplo getopt-parse.bash .Há também um
getopts_long
escrito como uma função shell.fonte
getopt
foi incluído no FreeBSD versão 1.0 em 1993 e faz parte do FreeBSD desde então. Como tal, foi adotado no FreeBSD 4.x para inclusão no projeto Darwin da Apple. A partir do OS X 10.6.8, a página de manual incluída pela Apple continua sendo uma duplicata exata da página de manual do FreeBSD. Então, sim, ele está incluído no OS X e em outros sistemas operacionais, além do Linux. -1 nesta resposta para informações incorretas..
fonte
"${1:0:1}"
para o argumento nº 1, substring no índice 0, comprimento 1. Isso não permite misturar opções curtas e longas.Em
ksh93
,getopts
suporta nomes longos ...Ou então os tutoriais que eu encontrei disseram. Experimente e veja.
fonte
Eu só escrevo shell scripts de vez em quando e saio da prática, para que qualquer feedback seja apreciado.
Usando a estratégia proposta pelo @Arvid Requate, notamos alguns erros do usuário. Um usuário que se esquece de incluir um valor acidentalmente terá o nome da próxima opção tratado como um valor:
fará com que o valor de "loglevel" seja visto como "--toc = TRUE". Isso pode ser evitado.
Adaptei algumas idéias sobre a verificação de erro do usuário para a CLI na http://mwiki.wooledge.org/BashFAQ/035 discussão sobre análise manual. Eu inseri a verificação de erros no tratamento dos argumentos "-" e "-".
Então comecei a brincar com a sintaxe, para que qualquer erro aqui seja estritamente minha culpa, não dos autores originais.
Minha abordagem ajuda os usuários que preferem entrar muito tempo com ou sem o sinal de igual. Ou seja, ele deve ter a mesma resposta para "--loglevel 9" que "--loglevel = 9". No método - / space, não é possível saber com certeza se o usuário esquece um argumento; portanto, é necessário adivinhar.
Caso você esteja começando com isso, há uma diferença interessante entre os formatos "--opt = value" e "--opt value". Com o sinal de igual, o argumento da linha de comando é visto como "opt = value" e o trabalho para manipular a análise de cadeia de caracteres, para separar no "=". Por outro lado, com "--opt value", o nome do argumento é "opt" e temos o desafio de obter o próximo valor fornecido na linha de comando. É aí que o @Arvid Requate usou $ {! OPTIND}, a referência indireta. Ainda não entendo isso, bem, e os comentários no BashFAQ parecem alertar contra esse estilo ( http://mywiki.wooledge.org/BashFAQ/006 ). BTW, eu não acho que os comentários do pôster anterior sobre a importância de OPTIND = $ (($ OPTIND + 1)) estejam corretos. Eu quis dizer,
Na versão mais recente desse script, o sinalizador -v significa impressão VERBOSE.
Salve-o em um arquivo chamado "cli-5.sh", torne o executável e qualquer um deles funcionará ou falhará da maneira desejada
Aqui está um exemplo de saída da verificação de erro no usuário intpu
Você deve ativar a opção -v, pois ela imprime as partes internas do OPTIND e OPTARG
fonte
OPTIND=$(( $OPTIND + 1 ))
: é necessário sempre que você "devora" o parâmetro do OPTIND (por exemplo: quando um usado--toc value
: value está no número do parâmetro $ OPTIND. Depois de recuperá-lo para o valor de toc, você deve informar ao getopts que o próximo parâmetro a analisar não é valor, mas o que está depois dele (daí o:.OPTIND=$(( $OPTIND + 1 ))
e seu script (assim como o script a que você se refere) está ausente, depois do feito:shift $(( $OPTIND -1 ))
(como getopts saiu após analisar os parâmetrosrs 1 a OPTIND-1, é necessário alterá-los para que$@
está agora qualquer restantes "não-opções" parâmetrosInventando mais uma versão do volante ...
Esta função é (esperançosamente) uma substituição simples do shell bourne compatível com POSIX para o GNU getopt. Ele suporta opções curtas / longas que podem aceitar argumentos obrigatórios / opcionais / sem argumentos, e a maneira como as opções são especificadas é quase idêntica à GNU getopt, portanto a conversão é trivial.
É claro que este ainda é um pedaço considerável de código a ser inserido em um script, mas é cerca de metade das linhas da conhecida função shell getopt_long, e pode ser preferível nos casos em que você deseja substituir apenas os usos existentes do GNU getopt.
Este é um código bastante novo, então YMMV (e definitivamente por favor me avise se isso não é realmente compatível com POSIX por qualquer motivo - portabilidade era a intenção desde o início, mas eu não tenho um ambiente de teste POSIX útil).
O código e o exemplo de uso a seguir:
Exemplo de uso:
fonte
A resposta aceita faz um trabalho muito bom de apontar todas as deficiências do bash embutido
getopts
. A resposta termina com:E, apesar de concordar em princípio com essa afirmação, sinto que o número de vezes que todos implementamos esse recurso em vários scripts justifica um pouco de esforço na criação de uma solução "padronizada" e bem testada.
Como tal, eu "atualizei" o bash embutido
getopts
implementandogetopts_long
o bash puro, sem dependências externas. O uso da função é 100% compatível com o built-ingetopts
.Ao incluir
getopts_long
( hospedado no GitHub ) em um script, a resposta para a pergunta original pode ser implementada da seguinte maneira:fonte
Ainda não tenho representante suficiente para comentar ou votar em sua solução, mas a resposta da sme funcionou extremamente bem para mim. O único problema que encontrei foi que os argumentos acabam em aspas simples (então, eu os retiro).
Também adicionei alguns exemplos de uso e texto de AJUDA. Vou incluir minha versão um pouco estendida aqui:
fonte
Aqui você pode encontrar algumas abordagens diferentes para a análise de opções complexas no bash: http://mywiki.wooledge.org/ComplexOptionParsing
Eu criei o seguinte e acho que é bom, porque é um código mínimo e as opções longas e curtas funcionam. Uma opção longa também pode ter vários argumentos com essa abordagem.
fonte
Estou trabalhando nesse assunto há muito tempo ... e criei minha própria biblioteca, que você precisará obter no seu script principal. Veja libopt4shell e cd2mpc para um exemplo. Espero que ajude !
fonte
Uma solução aprimorada:
fonte
Talvez seja mais simples usar o ksh, apenas para a parte getopts, se precisar de longas opções de linha de comando, pois pode ser mais fácil fazer isso lá.
fonte
Eu queria algo sem dependências externas, com suporte estrito ao bash (-u), e precisava que ele funcionasse mesmo nas versões mais antigas do bash. Isso lida com vários tipos de parâmetros:
Basta inserir o seguinte na parte superior do seu script:
E use-o assim:
fonte
Para manter a compatibilidade entre plataformas e evitar a dependência de executáveis externos, eu portava algum código de outro idioma.
Eu acho muito fácil de usar, aqui está um exemplo:
O BASH necessário é um pouco mais longo do que poderia ser, mas eu queria evitar a dependência das matrizes associativas do BASH 4. Você também pode fazer o download diretamente em http://nt4.com/bash/argparser.inc.sh
fonte
Se todas as suas opções longas tiverem primeiros caracteres únicos e correspondentes como as opções curtas, por exemplo, por exemplo
É o mesmo que
Você pode usar isso antes de getopts para reescrever $ args:
Obrigado por mtvee pela inspiração ;-)
fonte
se simplesmente é assim que você deseja chamar o script
então você pode seguir esta maneira mais simples de alcançá-lo com a ajuda de getopt e --longoptions
tente isso, espero que seja útil
fonte
getopts "poderia ser usado" para analisar opções longas, desde que você não espere que elas tenham argumentos ...
Veja como:
Se você tentar usar OPTIND para obter um parâmetro para a opção long, getopts o tratará como o primeiro parâmetro posicional não opcional e interromperá a análise de outros parâmetros. Nesse caso, será melhor manipulá-lo manualmente com uma simples declaração de caso.
Isso "sempre" funcionará:
Embora não seja tão flexível quanto getopts, você deve executar grande parte do código de verificação de erro nas instâncias do caso ...
Mas é uma opção.
fonte
O built-in
getopts
analisa apenas opções curtas (exceto no ksh93), mas você ainda pode adicionar poucas linhas de script para fazer com que o getopts lide com opções longas.Aqui está uma parte do código encontrado em http://www.uxora.com/unix/shell-script/22-handle-long-options-with-getopts
Aqui está um teste:
Caso contrário, no recente Korn Shell ksh93, é
getopts
possível analisar naturalmente opções longas e até exibir uma página de manual. (Consulte http://www.uxora.com/unix/shell-script/20-getopts-with-man-page-and-long-options )fonte
Th built-in OS X (BSD) getopt não suporta opções longas, mas a versão GNU faz:
brew install gnu-getopt
. Então, algo semelhante a:cp /usr/local/Cellar/gnu-getopt/1.1.6/bin/getopt /usr/local/bin/gnu-getopt
.fonte
O EasyOptions lida com opções curtas e longas:
fonte