Atualmente, estou escrevendo um script Bash com os seguintes requisitos:
- deve ser executado em uma ampla variedade de plataformas Unix / Linux
- deve suportar opções curtas e longas (GNU)
Eu sei que getopts
seria a maneira preferida em termos de portabilidade, mas o AFAIK não suporta opções longas.
getopt
suporta opções longas, mas o BashGuide recomenda fortemente:
Nunca use getopt (1). O getopt não pode manipular cadeias de argumentos vazias ou argumentos com espaço em branco incorporado. Por favor, esqueça que ele já existiu.
Portanto, ainda há a opção de análise manual. Isso é propenso a erros, produz bastante código padrão, e eu preciso lidar com os erros sozinho (acho getopt(s)
que o tratamento de erros sozinho).
Então, qual seria a escolha preferida neste caso?
bash
shell-script
options
user-interface
getopts
helpermethod
fonte
fonte
Respostas:
Se precisar ser portátil para uma variedade de Unices, você precisará seguir o POSIX sh. E no AFAIU, você simplesmente não tem escolha, a não ser manipular argumentos manualmente.
fonte
getopt
vsgetopts
parece ser uma questão religiosa. Quanto aos argumentos contragetopt
no Bash FAQ :"
getopt
não pode lidar com cadeias de argumentos vazias" parece se referir a um problema conhecido com argumentos opcionais , que parecegetopts
não ter suporte (pelo menos na leiturahelp getopts
do Bash 4.2.24). Deman getopt
:Não sei de onde
getopt
vem o " não pode lidar com [...] argumentos com espaço em branco incorporado", mas vamos testá-lo:test.sh:
corre:
Parece verificar e acasalar comigo, mas tenho certeza que alguém vai mostrar como eu entendi completamente a frase. Claro que a questão da portabilidade ainda permanece; você terá que decidir quanto tempo vale a pena investir em plataformas com um Bash mais antigo ou sem disponibilidade. Minha dica é usar as diretrizes YAGNI e KISS - Desenvolva apenas para plataformas específicas que você sabe que serão usadas. A portabilidade do código do shell geralmente chega a 100% conforme o tempo de desenvolvimento chega ao infinito.
fonte
getopt
você está citando aqui é específico do Linux. Note que issogetopt
não faz partebash
, nem é um utilitário GNU e no Linux é fornecido com o pacote util-linux.getopt
, apenas o Linux AFAIK vem com um que suporta opções longas ou espaços em branco nos argumentos. Os outros suportariam apenas a sintaxe do System V.getopt
é um comando tradicional que vem do System V muito antes do Linux ser lançado.getopt
nunca foi padronizado. Nenhum POSIX, Unix ou Linux (LSB) padronizou ogetopt
comando.getopts
é especificado nos três, mas sem suporte para opções longas.getopt
. É o sabor linux-utils, conforme indicado por @ StéphaneChazelas. Possui opções herdadas que desabilitam a sintaxe descrita acima, em particular a página de manual declara "GETOPT_COMPATIBLE força o getopt a usar o primeiro formato de chamada, conforme especificado na SINOPSE". No entanto, se você pode esperar sistemas de destino para ter este pacote instalado isso é totalmente o caminho a percorrer, como o getopt original está horrível e getopt do Bash é muito limitadoHá esse getopts_long escrito como uma função de shell POSIX que você pode incorporar ao seu script.
Observe que o Linux
getopt
(fromutil-linux
) funciona corretamente quando não está no modo tradicional e suporta opções longas, mas provavelmente não é uma opção para você se você precisar ser portátil para outros Unices.As versões recentes do ksh93 (
getopts
) e zsh (zparseopts
) têm suporte interno para analisar opções longas, que podem ser uma opção para você, pois estão disponíveis para a maioria dos Unices (embora muitas vezes não sejam instaladas por padrão).Outra opção seria usar
perl
e seuGetopt::Long
módulo, que deve estar disponível na maioria dos Unices atualmente, escrevendo o script inteiroperl
ou apenas chamando perl apenas para analisar a opção e alimentar as informações extraídas para o shell. Algo como:Veja o
perldoc Getopt::Long
que ele pode fazer e como ele difere de outros analisadores de opções.fonte
Toda discussão sobre esse assunto destaca a opção de escrever o código de análise manualmente - somente então você pode ter certeza sobre a funcionalidade e a portabilidade. Eu aconselho você a não escrever código que possa ter gerado e recriado por geradores de código-fonte aberto fáceis de usar. Use Argbash , que foi projetado para fornecer a resposta definitiva para o seu problema. É um gerador de código bem documentado disponível como um aplicativo de linha de comando , online ou como uma imagem do Docker .
Eu desaconselho as bibliotecas bash, algumas delas usam
getopt
(o que torna bastante portável) e é doloroso agrupar um blob gigantesco de shell ilegível com seu script.fonte
Você pode usar
getopt
em sistemas que o suportam e usar um fallback para sistemas que não o suportam.Por exemplo,
pure-getopt
é implementado no Bash puro para substituir o GNUgetopt
.fonte