Como usar testes condicionais de colchete duplo no Linux

Publicados: 2022-01-29
fatmawati achmad zaenuri/Shutterstock.com

Testes condicionais ramificam o fluxo de execução de scripts Linux Bash de acordo com o resultado de uma expressão lógica. Testes condicionais de colchetes duplos simplificam consideravelmente a sintaxe, mas ainda têm suas próprias pegadinhas.

Suportes simples e duplos

Bash fornece o comando de test . Isso permite testar expressões lógicas. A expressão retornará uma resposta que indica uma resposta verdadeira ou falsa. Uma resposta verdadeira é indicada por um valor de retorno de zero. Qualquer coisa diferente de zero indica falso.

O encadeamento de comandos na linha de comando com o operador && usa esse recurso. Os comandos só são executados se o comando anterior for concluído com êxito.

Se o teste for verdadeiro, a palavra “Sim” será impressa.

 teste 15 -eq 15 && echo "Sim"
 teste 14 -eq 15 && echo "Sim" 

Exemplos simples do comando de teste Bash

Os testes condicionais de colchete único imitam o comando de test . Eles envolvem a expressão entre colchetes “ [ ] ” e operam exatamente como o comando test . Na verdade, eles são o mesmo programa, criado a partir do mesmo código-fonte. A única diferença operacional é como a versão de test e a versão [ lidam com solicitações de ajuda.

Isso é do código-fonte:

 /* Reconhece --help ou --version, mas somente quando invocado no
"[" formulário, quando o último argumento não é "]". Usar direto
parsing, em vez de parse_long_options, para evitar aceitar
abreviaturas. POSIX permite "[ --help" e "[ --version" para
tem o comportamento normal do GNU, mas requer "test --help"
e "test --version" para sair silenciosamente com status 0. */
Propaganda

Podemos ver o efeito disso pedindo ajuda a test e [ e verificando o código de resposta enviado ao Bash.

 teste --ajuda
 eco $?
 [ --ajuda
 eco $? 

Usando --help no teste e [

Ambos test e [ são internos do shell , o que significa que eles são inseridos diretamente no Bash. Mas há também uma versão binária autônoma de [ .

 teste de tipo
 modelo [
 Onde é [ 

Encontrando os diferentes tipos de comandos [ e test

Por outro lado, os testes condicionais de colchetes duplos [[ e ]] são palavras- chave . [[ e ]] também realizam testes lógicos, mas sua sintaxe é diferente. Por serem palavras-chave, você pode usar alguns recursos interessantes que não funcionarão na versão de colchete único.

As palavras-chave de colchetes duplos são suportadas pelo Bash, mas não estão disponíveis em todos os outros shells. Por exemplo, o shell Korn os suporta, mas o shell antigo, sh, não. Todos os nossos scripts começam com a linha:

 #!/bin/bash

Isso garante que estamos chamando o shell Bash para executar o script.

RELACIONADO: Como criar e executar scripts de shell Bash no Windows 10

Integrações e palavras-chave

Podemos usar o programa compgen para listar os builtins:

 compgen -b | fmt -w 70
Propaganda

Sem canalizar a saída através do fmt , obteríamos uma longa lista com cada um embutido em sua própria linha. É mais conveniente neste caso ver os builtins agrupados em um parágrafo.

Listando os internos do Bash

Podemos ver test e [ na lista, mas ] não está listado. O comando [ procura um fechamento ] para detectar quando atingiu o final da expressão, mas ] não é um builtin separado. É apenas um sinal que damos a [ para indicar o fim da lista de parâmetros.

Para ver as palavras-chave, podemos usar:

 compgen -k | fmt -w 70 

Listando as palavras-chave do Bash

As palavras-chave [[ e ]] estão ambas na lista, porque [[ é uma palavra-chave e ]] é outra. Eles são um par combinado, assim como if e fi , e case e esac .

Quando o Bash está analisando um script - ou uma linha de comando - e detecta uma palavra-chave que possui uma palavra-chave de fechamento correspondente, ele reúne tudo o que aparece entre eles e aplica qualquer tratamento especial que as palavras-chave suportem.

Com um builtin, o que segue o comando embutido é passado para ele exatamente como parâmetros para qualquer outro programa de linha de comando. Isso significa que um cuidado especial deve ser tomado pelo autor do script em relação a coisas como espaços em valores de variáveis.

Globbing de conchas

Testes condicionais de colchetes duplos podem fazer uso de globbing de shell. Isso significa que o asterisco “ * ” se expandirá para significar “qualquer coisa”.

Propaganda

Digite ou copie o seguinte texto em um editor e salve-o em um arquivo chamado “whelkie.sh”.

 #!/bin/bash

stringvar="Whelkie Brookes"

if [[ "$stringvar" == *elk* ]];
então
  echo "Aviso contém frutos do mar"
senão
  echo "Livre de moluscos"
fi

Para tornar o script executável, precisaremos usar o comando chmod com a opção -x (execute). Você precisará fazer isso com todos os scripts deste artigo se quiser experimentá-los.

 chmod +x whelkie.sh 

Usando chmod para tornar um script executável

Quando executamos o script, vemos que a string “elk” foi encontrada na string “Whelkie”, independentemente de quais outros caracteres a cercam.

 ./whelkie.sh 

Executando o script whelkie.sh

Um ponto a ser observado é que não colocamos a string de pesquisa entre aspas duplas. Se você fizer isso, o globbing não vai acontecer. A string de pesquisa será tratada literalmente.

Outras formas de globbing de conchas são permitidas. O ponto de interrogação “ ? ” corresponderá a caracteres simples e colchetes simples são usados ​​para indicar intervalos de caracteres. Por exemplo, se você não souber qual case usar, poderá cobrir ambas as eventualidades com um intervalo.

 #!/bin/bash

stringvar="Jean-Claude van Clam"

if [[ "$stringvar" == *[cC]lam* ]];
então
  echo "Aviso contém frutos do mar."
senão
  echo "Livre de moluscos."
fi

Salve este script como “damme.sh” e torne-o executável. Quando a executamos, a instrução condicional resolve para true e a primeira cláusula da instrução if é executada.

 ./damme.sh 

Executando o script damme.sh

Strings de citação

Mencionamos anteriormente envolver strings entre aspas duplas. Se você fizer isso, o shell globbing não ocorrerá. Embora a convenção diga que é uma boa prática, você não precisa envolver variáveis ​​de string entre aspas ao usar [[ e ]] , mesmo que contenham espaços. Veja o próximo exemplo. As variáveis ​​de string $stringvar e $surname contêm espaços, mas nenhuma delas é citada na instrução condicional.

 #!/bin/bash

stringvar="van Damme"
sobrenome="van Damme"

if [[ $stringvar == $sobrenome]];
então
echo "Sobrenomes coincidem."
senão
echo "Os sobrenomes não combinam."
fi
Propaganda

Salve isso em um arquivo chamado “surname.sh” e torne-o executável. Execute-o usando:

 ./sobrenome.sh 

Executando o script sobrenome.sh

Apesar de ambas as strings conterem espaços, o script é bem-sucedido e a instrução condicional é resolvida como verdadeira. Isso é útil ao lidar com caminhos e nomes de diretório que contêm espaços. Aqui, a opção -d retorna true se a variável contiver um nome de diretório válido.

 #!/bin/bash

dir="/home/dave/Documents/Needs Work"

if [[ -d ${dir}]];
então
  echo "Diretório confirmado"
senão
  echo "Diretório não encontrado"
fi

Se você alterar o caminho no script para refletir um diretório em seu próprio computador, salve o texto em um arquivo chamado “dir.sh” e torne-o executável, você verá que isso funciona.

 ./dir.sh 

Executando o script dir.sh

RELACIONADO: Como trabalhar com variáveis ​​no Bash

Nome de arquivo Globbing Gotchas

Uma diferença interessante entre [ ] e [[ ]] está relacionada aos nomes de arquivos com globbing neles. O formulário “*.sh” corresponderá a todos os arquivos de script. O uso de colchetes simples [ ] falha, a menos que haja um único arquivo de script. Encontrar mais de um script gera um erro.

Aqui está o script com condicionais de colchete único.

 #!/bin/bash

if [ -a *.sh ];
então
  echo "Encontrou um arquivo de script"
senão
  echo "Não encontrou um arquivo de script"
fi

Salvamos este texto em “script.sh” e o tornamos executável. Verificamos quantos scripts estavam no diretório e executamos o script.

 ls
 ./script.sh 

Executando o script script.sh

Propaganda

Bash lança um erro. Removemos todos os arquivos de script, exceto um, e executamos o script novamente.

 ls
 ./script.sh 

Executando o script script.sh com um único script no diretório

O teste condicional retorna verdadeiro e o script não causa erro. Editar o script para usar colchetes duplos fornece um terceiro tipo de comportamento.

 #!/bin/bash

if [[ -a *.sh ]];
então
  echo "Encontrou um arquivo de script"
senão
  echo "Não encontrou um arquivo de script"
fi

Nós salvamos isso em um arquivo chamado “dscript.sh” e o tornamos executável. A execução desse script em um diretório com muitos scripts não gera um erro, mas o script não reconhece nenhum arquivo de script.

A instrução condicional usando colchetes duplos só resolve para true no caso improvável de você ter um arquivo realmente chamado “*.sh” no diretório.

 ./dscript.sh 

Executando o script dscript.sh

E e OU lógicos

Os colchetes duplos permitem que você use && e || como os operadores lógicos AND e OR.

Esse script deve resolver a instrução condicional como verdadeira porque 10 é igual a 10 e 25 é menor que 26.

 #!/bin/bash

primeiro = 10
segundo=25

if [[ primeiro -eq 10 && segundo -lt 26 ]];
então
  echo "Condição atendida"
senão
  echo "Falha na condição"
fi
Propaganda

Salve este texto em um arquivo chamado “and.sh”, torne-o executável e execute-o com:

 ./and.sh 

Executando o script and.sh

O script é executado como esperávamos.

Desta vez, usaremos o || operador. A instrução condicional deve ser resolvida como verdadeira porque, embora 10 não seja maior que 15, 25 ainda é menor que 26. Desde que a primeira comparação ou a segunda comparação seja verdadeira, a instrução condicional como um todo é resolvida como verdadeira.

Salve este texto como “or.sh” e torne-o executável.

 #!/bin/bash

primeiro = 10
segundo=25

if [[ primeiro -gt 15 || segundo -lt 26 ]];
então
  echo "Condição atendida."
senão
  echo "Falha na condição."
fi
 ./ou.sh 

Executando o script or.sh

Regexes

As instruções condicionais de colchetes duplos permitem o uso do operador =~ , que aplica os padrões de pesquisa regex em uma string à outra metade da instrução. Se a regex for satisfeita, a instrução condicional é considerada verdadeira. Se a regex não encontrar correspondências, a instrução condicional será resolvida como falsa.

RELACIONADO: Como usar expressões regulares (regexes) no Linux

Salve este texto em um arquivo chamado “regex.sh” e torne-o executável.

 #!/bin/bash

palavras = "um dois três"
WordsandNumbers="um 1 dois 2 três 3"
email="[email protected]"

mascara1="[0-9]"
mask2="[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+.[A-Za-z]{2,4}"

if [[ $palavras =~ $mask1]];
então
  echo "\"$words\" contém dígitos."
senão
  echo "Nenhum dígito encontrado em \"$words\"."
fi

if [[ $WordsandNumbers =~ $mask1]];
então
  echo "\"$WordsandNumbers\" contém dígitos."
senão
  echo "Nenhum dígito encontrado em \"$WordsandNumbers\"."
fi

if [[ $email =~ $mask2]];
então
  echo "\"$email\" é um endereço de e-mail válido."
senão
  echo "Não foi possível analisar \"$email\"."
fi

O primeiro conjunto de colchetes duplos usa a variável de string $mask1 como regex. Este contém o padrão para todos os dígitos no intervalo de zero a nove. Ele aplica esse regex à variável de string $words .

O segundo conjunto de colchetes duplos novamente usa a variável de string $mask1 como regex, mas desta vez a usa com a variável de string $WordsandNumbers .

Propaganda

O último conjunto de colchetes duplos usa uma máscara regex mais complexa na variável de string $mask2 .

  • [A-Za-z0-9._%+-]+ : corresponde a qualquer caractere que seja uma letra maiúscula ou minúscula, ou qualquer dígito de zero a nove, ou um ponto, sublinhado, sinal de porcentagem ou sinal de mais ou menos . O “ + ” fora do “ [] ” significa repetir essas correspondências para quantos caracteres encontrar.
  • @ : Isso corresponde apenas ao caractere “@”.
  • [A-Za-z0-9.-]+ : Corresponde a qualquer caractere que seja uma letra maiúscula ou minúscula, ou qualquer dígito de zero a nove, ou um ponto ou hífen. O “ + ” fora do “ [ ] ” significa repetir essas correspondências para quantos caracteres encontrar.
  • . : Isso corresponde ao “.” personagem apenas.
  • [A-Za-z]{2,4} : Isso corresponde a qualquer letra maiúscula ou minúscula. O “ {2,4} ” significa corresponder pelo menos dois caracteres e no máximo quatro.

Juntando tudo isso, a máscara regex verificará se um endereço de e-mail está formado corretamente.

Salve o texto do script em um arquivo chamado “regex.sh” e torne-o executável. Quando executamos o script, obtemos essa saída.

 ./regex.sh 

Executando o script regex.sh

A primeira instrução condicional falha porque o regex está procurando por dígitos, mas não há dígitos no valor contido na variável de string $words .

A segunda instrução condicional é bem-sucedida porque a variável de string $WordsandNumbers contém dígitos.

Propaganda

A instrução condicional final é bem-sucedida — ou seja, resolve como verdadeira — porque o endereço de e-mail está formatado corretamente.

Apenas uma condição

Testes condicionais de colchetes duplos trazem flexibilidade e legibilidade aos seus scripts. Apenas poder usar regexes em seus testes condicionais justifica aprender a usar [[ e ]] .

Apenas certifique-se de que o script chame um shell que os suporte, como o Bash.

RELACIONADO: 15 caracteres especiais que você precisa conhecer para Bash