Categories: Tecnologia

Como usar getopts para analisar opções de script de shell do Linux

fatmawati achmad zaenuri/Shutterstock.com

Você deseja que seus scripts de shell do Linux lidem com opções e argumentos de linha de comando com mais facilidade? O Bash getoptsintegrado permite analisar opções de linha de comando com sutileza – e também é fácil. Nós mostramos-lhe como.

Apresentando o getopts embutido

Passar  valores  para um script Bash é uma questão bastante simples. Você chama seu script da linha de comando ou de outro script e fornece sua lista de valores por trás do nome do script. Esses valores podem ser acessados ​​dentro do seu script como variáveis , começando $1pela primeira variável, $2pela segunda e assim por diante.

Mas se você quiser passar  opções  para um script, a situação rapidamente se torna mais complexa. Quando dizemos opções, queremos dizer as opções, sinalizadores ou opções que programas como lspodem manipular. Eles são precedidos por um traço “ -” e geralmente atuam como um indicador para o programa ativar ou desativar algum aspecto de sua funcionalidade.

O lscomando possui mais de 50 opções, principalmente relacionadas à formatação de sua saída. A -Xopção (classificar por extensão) classifica a saída em ordem alfabética por extensão de arquivo . A -Uopção (não classificada) lista por ordem de diretório .

As opções são apenas isso — são opcionais. Você não sabe quais opções – se houver alguma – o usuário vai escolher usar, e também não sabe em que ordem eles podem listá-las na linha de comando . Isso aumenta a complexidade do código necessário para analisar as opções.

As coisas se tornam ainda mais complicadas se algumas de suas opções receberem um argumento, conhecido como  argumento de opção , Por exemplo, a ls -wopção (largura) espera ser seguida por um número, representando a largura máxima de exibição da saída. E, claro, você pode estar passando outros parâmetros em seu script que são simplesmente valores de dados, que não são opções.

Felizmente getoptslida com essa complexidade para você. E porque é um built-in, está disponível em todos os sistemas que possuem o shell Bash, então não há nada para instalar.

Nota: getopts Não getopt

Existe um utilitário mais antigo chamado getopt. Este é um pequeno programa utilitário  , não um built-in. Existem muitas versões diferentes getoptcom comportamentos diferentes, enquanto o  getopsbuilt-in segue as diretrizes POSIX.

digite getopts
digite getopt

Como getoptnão é um built-in, ele não compartilha alguns dos benefícios automáticos que o getopts  faz, como lidar com espaços em branco de maneira sensata. Com getopts, o shell Bash está executando seu script e o shell Bash está fazendo a análise de opções. Você não precisa invocar um programa externo para lidar com a análise.

A desvantagem é getoptsnão lidar com nomes de opções de formato longo e com travessão duplo. Então você pode usar opções formatadas como -w  mas não ” ---wide-format.” Por outro lado, se você tiver um script que aceite as opções -a, -b, e   -c, getoptspermite combiná-las como -abc, -bca, ou -bace assim por diante.

Estamos discutindo e demonstrando   getopts neste artigo, portanto, certifique-se de adicionar o “s” final ao nome do comando.

Uma recapitulação rápida: como lidar com valores de parâmetros

Este script não usa opções tracejadas como -aou -b. Ele aceita parâmetros “normais” na linha de comando e estes são acessados ​​dentro do script como valores.

#!/bin/bash

# pega as variaveis uma a uma
echo "Variável Um: $1"
echo "Variável dois: $2"
echo "Variável três: $3"

# percorre as variáveis
for var em " $@" faça 
  echo "$ var"
feito

Os parâmetros são acessados ​​dentro do script como variáveis $1​​, $2ou $3.

Copie este texto em um editor e salve-o como um arquivo chamado “variables.sh”. Precisaremos torná-lo executável com o chmodcomando . Você precisará fazer esta etapa para todos os scripts que discutimos. Basta substituir o nome do arquivo de script apropriado a cada vez.

chmod +x variáveis.sh

Se executarmos nosso script sem parâmetros, obteremos essa saída.

./variables.sh

Não passamos parâmetros para que o script não tenha valores para relatar. Vamos fornecer alguns parâmetros desta vez.

./variables.sh como nerd

Como esperado, as variáveis $1​​, $2, e $3foram definidas para os valores dos parâmetros e os vemos impressos.

Esse tipo de manipulação de parâmetros um por um significa que precisamos saber com antecedência quantos parâmetros haverá. O loop na parte inferior do script não se importa com quantos parâmetros existem, ele sempre percorre todos eles.

Se fornecermos um quarto parâmetro, ele não será atribuído a uma variável, mas o loop ainda o tratará.

./variables.sh como fazer um site geek

Se colocarmos aspas em torno de duas das palavras, elas serão tratadas como um parâmetro.

./variables.sh como "para geek"

Se precisarmos que nosso script lide com todas as combinações de opções, opções com argumentos e parâmetros de tipo de dados “normais”, precisaremos separar as opções dos parâmetros regulares. Podemos conseguir isso colocando todas as opções — com ou sem argumentos — antes dos parâmetros regulares.

Mas não vamos correr antes de podermos andar. Vejamos o caso mais simples para lidar com opções de linha de comando.

Opções de manuseio

Usamos getoptsem whileloop. Cada iteração do loop funciona em uma opção que foi passada para o script. Em cada caso, a variável OPTIONé definida para a opção identificada por getopts.

A cada iteração do loop, getoptspassa para a próxima opção. Quando não há mais opções, getoptsretorna falsee o whileloop é encerrado.

A OPTIONvariável é comparada com os padrões em cada uma das cláusulas da instrução case. Como estamos usando uma instrução case , não importa a ordem em que as opções são fornecidas na linha de comando. Cada opção é descartada na instrução case e a cláusula apropriada é acionada.

As cláusulas individuais na instrução case facilitam a execução de ações específicas de opções no script. Normalmente, em um script do mundo real, você definiria uma variável em cada cláusula, e isso funcionaria como sinalizadores mais adiante no script, permitindo ou negando alguma funcionalidade.

Copie este texto em um editor e salve-o como um script chamado “options.sh” e torne-o executável.

#!/bin/bash

enquanto getopts 'abc' OPÇÃO; Faz
  caso "$OPTION" em
    a)
      echo "Opção a usada" ;;

    b)
      echo "Opção b usada"
      ;;

    c)
      echo "Opção c usada"
      ;;

    ?)
      echo "Uso: $(basename $0) [-a] [-b] [-c]"
      saída 1
      ;;
  esac
feito

Esta é a linha que define o loop while.

enquanto getopts 'abc' OPÇÃO; Faz

O getoptscomando é seguido pela  string de opções . Isso lista as letras que vamos usar como opções. Apenas letras nesta lista podem ser usadas como opções. Portanto, neste caso, -dseria inválido. Isso seria capturado pela ?)cláusula porque getoptsretorna um ponto de interrogação “ ?” para uma opção não identificada. Se isso acontecer, o uso correto é impresso na janela do terminal:

echo "Uso: $(basename $0) [-a] [-b] [-c]"

Por convenção, colocar uma opção entre colchetes “ []” neste tipo de mensagem de uso correto significa que a opção é opcional. O comando basename remove qualquer caminho de diretório do nome do arquivo. O nome do arquivo de script é mantido em $0scripts Bash.

Vamos usar este script com diferentes combinações de linha de comando.

./options.sh -a
./options.sh -a -b -c
./options.sh -ab -c
./options.sh -cab

Como podemos ver, todas as nossas combinações de teste de opções são analisadas e tratadas corretamente. E se tentarmos uma opção que não existe?

./options.sh -d

A cláusula de uso é acionada, o que é bom, mas também recebemos uma mensagem de erro do shell. Isso pode ou não importar para o seu caso de uso. Se você estiver chamando o script de outro script que precisa analisar mensagens de erro, ficará mais difícil se o shell também estiver gerando mensagens de erro.

Desligar as mensagens de erro do shell é muito fácil. Tudo o que precisamos fazer é colocar dois pontos ” :” como o primeiro caractere da string de opções.

Edite seu arquivo “options.sh” e adicione dois pontos como o primeiro caractere da string de opções, ou salve este script como “options2.sh” e torne-o executável.

#!/bin/bash

while getopts ':abc' OPÇÃO; Faz
  caso "$OPTION" em
    a)
      echo "Opção a usada"
      ;;

    b)
      echo "Opção b usada"
      ;;

    c)
      echo "Opção c usada"
      ;;

    ?)
      echo "Uso: $(basename $0) [-a] [-b] [-c]"
      saída 1
      ;;
  esac
feito

Quando executamos isso e geramos um erro, recebemos nossas próprias mensagens de erro sem nenhuma mensagem de shell.

./options2.sh.sh -d

Usando getopts com argumentos de opção

Para dizer getoptsque uma opção será seguida por um argumento, coloque dois pontos ” :” imediatamente após a letra da opção na string de opções.

Se seguirmos o “b” e o “c” em nossa string de opções com dois pontos, getoptesperaremos argumentos para essas opções. Copie este script em seu editor e salve-o como “arguments.sh” e torne-o executável.

Lembre-se, os  primeiros  dois pontos na string de opções são usados ​​para suprimir mensagens de erro do shell – não tem nada a ver com o processamento de argumentos.

Quando getoptprocessa uma opção com um argumento, o argumento é colocado na OPTARGvariável. Se você quiser usar esse valor em outro lugar em seu script, precisará copiá-lo para outra variável.

#!/bin/bash

while getopts ':ab:c:' OPÇÃO; Faz

  caso "$OPTION" em
    a)
      echo "Opção a usada"
      ;;

    b)
      argB="$OPTARG"
      echo "Opção b usada com: $argB"
      ;;

    c)
      argC="$OPTARG"
      echo "Opção c usada com: $argC"
      ;;

    ?)
      echo "Uso: $(basename $0) [-a] [-b argumento] [-c argumento]"
      saída 1
      ;;
  esac

feito

Vamos executar isso e ver como funciona.

./arguments.sh -a -b "como nerd" -c reviewgeek
./arguments.sh -c reviewgeek -a

Portanto, agora podemos lidar com opções com ou sem argumentos, independentemente da ordem em que são fornecidas na linha de comando.

Mas e os parâmetros regulares? Dissemos anteriormente que sabíamos que teríamos que colocá-los na linha de comando após qualquer opção. Vamos ver o que acontece se o fizermos.

Opções e parâmetros de mistura

Vamos mudar nosso script anterior para incluir mais uma linha. Quando o whileloop for encerrado e todas as opções tiverem sido tratadas, tentaremos acessar os parâmetros regulares. Vamos imprimir o valor em $1.

Salve este script como “arguments2.sh” e torne-o executável.

#!/bin/bash

while getopts ':ab:c:' OPÇÃO; Faz

  caso "$OPTION" em
    a)
      echo "Opção a usada"
      ;;

    b)
      argB="$OPTARG"
      echo "Opção b usada com: $argB"
      ;;

    c)
      argC="$OPTARG"
      echo "Opção c usada com: $argC"
      ;;

    ?)
      echo "Uso: $(basename $0) [-a] [-b argumento] [-c argumento]"
      saída 1
      ;;
  esac

feito

echo "A variável um é: $1"

Agora vamos tentar algumas combinações de opções e parâmetros.

./arguments2.sh dave
./arguments2.sh -a dave
./arguments2.sh -a -c how-to-geek dave

Então agora podemos ver o problema. Assim que qualquer opção é usada, as variáveis $1​​em diante são preenchidas com os sinalizadores de opção e seus argumentos. No último exemplo, $4manteria o valor do parâmetro “dave”, mas como você acessa isso em seu script se não sabe quantas opções e argumentos serão usados?

A resposta é usar OPTINDe o shiftcomando.

O shiftcomando descarta o primeiro parâmetro — independentemente do tipo — da lista de parâmetros. Os outros parâmetros são “shuffle down”, então o parâmetro 2 se torna o parâmetro 1, o parâmetro 3 se torna o parâmetro 2 e assim por diante. E assim $2se torna $1, $3se torna $2, e assim por diante.

Se você fornecer shiftum número, essa quantidade de parâmetros será retirada da lista.

OPTINDconta as opções e argumentos à medida que são encontrados e processados. Uma vez que todas as opções e argumentos tenham sido processados OPTIND, será um número maior que o número de opções. Então, se usarmos shift para cortar (OPTIND-1)parâmetros da lista de parâmetros, ficaremos com os parâmetros regulares em $1diante.

É exatamente isso que esse script faz. Salve este script como “arguments3.sh” e torne-o executável.

#!/bin/bash

while getopts ':ab:c:' OPÇÃO; Faz
  caso "$OPTION" em
    a)
      echo "Opção a usada"
      ;;

    b)
      argB="$OPTARG"
      echo "Opção b usada com: $argB"
      ;;

    c)
      argC="$OPTARG"
      echo "Opção c usada com: $argC"
      ;;

    ?)
      echo "Uso: $(basename $0) [-a] [-b argumento] [-c argumento]"
      saída 1
      ;;
  esac
feito

echo "Antes - variável um é: $1"
shift "$(($OPTIND -1))"
echo "Depois - variável um é: $1"
echo "O resto dos argumentos (operandos)"

para x em "$@"
Faz
  eco $ x
feito

Vamos executar isso com uma mistura de opções, argumentos e parâmetros.

./arguments3.sh -a -c how-to-geek "dave dee" dozy beaky mick tic

Podemos ver que antes de chamarmos shift, $1seguramos “-a”, mas depois que o comando shift $1mantém nosso primeiro parâmetro não-opção, não-argumento. Podemos percorrer todos os parâmetros tão facilmente quanto em um script sem análise de opções.

É sempre bom ter opções

Manipular opções e seus argumentos em scripts não precisa ser complicado. Com getoptsvocê pode criar scripts que lidam com opções de linha de comando, argumentos e parâmetros exatamente como scripts nativos compatíveis com POSIX deveriam.

maisroot

Recent Posts

O novo aplicativo “PC Manager” da Microsoft se parece muito com o CCleaner

Muitos aplicativos de limpeza estão disponíveis para Windows ao longo dos anos, mas hoje em…

1 ano ago

Como reiniciar um PS4

Seu PlayStation 4 está congelado? Seus jogos favoritos continuam travando? Reiniciar seu PS4 pode resolver…

1 ano ago

Veja por que as reticências são tão assustadoras ao enviar mensagens de texto…

A popularidade das mensagens de texto significou aprender uma forma totalmente nova de comunicação. Você…

1 ano ago

O telescópio James Webb acaba de capturar os “Pilares da Criação”

A foto dos "Pilares da Criação" tirada pelo Telescópio Espacial Hubble é uma das fotos…

1 ano ago

Você poderá baixar o Proton Drive mais cedo do que pensa

O Proton Drive saiu de seu estágio beta há algumas semanas, mas o aplicativo real…

1 ano ago

Como aumentar o zoom no Photoshop

Para ver suas fotos mais de perto ou para uma edição precisa , você pode…

1 ano ago