Operadores lógicos
Esta aula aborda os operadores lógicos em shell script: && (AND), || (OR) e ! (negação), explicando seu comportamento de curto-circuito e como encadear comandos de forma eficiente. Com exemplos práticos, você aprenderá a controlar o fluxo de execução baseado no sucesso ou falha de comandos anteriores.
Operadores lógicos são fundamentais em shell script para tomar decisões baseadas no status de saída de comandos. Eles permitem executar comandos condicionalmente, de forma concisa e sem a necessidade de estruturas if explícitas. Nesta aula, exploraremos os operadores &&, || e !, além do conceito de curto-circuito e técnicas de encadeamento.
No Bash, cada comando retorna um código de saída (exit code): 0 indica sucesso, e qualquer valor diferente de zero indica falha. Os operadores lógicos utilizam esses códigos para decidir se o próximo comando será executado. Dominar esses operadores torna seus scripts mais enxutos e legíveis.
&& e ||
O operador && (AND lógico) executa o comando à sua direita apenas se o comando à esquerda retornar sucesso (código 0). Já o operador || (OR lógico) executa o comando à direita apenas se o comando à esquerda falhar (código diferente de 0).
Exemplo prático: criar um diretório e, se bem-sucedido, entrar nele.
mkdir meu_diretorio && cd meu_diretorioSe o mkdir falhar (diretório já existe, permissão negada, etc.), o cd não será executado, evitando erros. Com o ||, podemos executar uma ação alternativa em caso de falha:
mkdir meu_diretorio || echo "Falha ao criar diretório"É comum combinar && e || para criar um if-else de uma linha:
comando && echo "Sucesso" || echo "Falha"Atenção: essa construção pode ter efeitos colaterais se o comando do meio falhar, pois o || será acionado. Para maior segurança, prefira if explícito em scripts complexos.
! (negação)
O operador ! inverte o código de saída de um comando: se o comando retorna 0 (sucesso), o ! faz com que o resultado seja 1 (falha) e vice-versa. É útil para executar um bloco apenas quando um comando falha, sem usar o ||.
! comando && echo "Comando falhou"Exemplo: verificar se um arquivo não existe antes de criar.
! test -f arquivo.txt && touch arquivo.txtO test -f retorna 0 se o arquivo existe. Com !, invertemos: se não existir (retorno 0 invertido para 1), o touch não executa? Na verdade, o ! nega o código, então se o arquivo não existe, test retorna 1 (falha), ! inverte para 0 (sucesso), e então o && executa o touch. Cuidado com a lógica: ! comando && proximo_comando executa proximo_comando se comando falhar (já que ! torna sucesso).
Curto-circuito
Os operadores && e || utilizam avaliação de curto-circuito: a expressão é avaliada da esquerda para a direita e a execução para assim que o resultado é determinado. Para &&, se o primeiro comando falha, o resultado já é falso, então o segundo não é executado. Para ||, se o primeiro comando tem sucesso, o resultado já é verdadeiro, então o segundo é ignorado.
Isso é útil para evitar comandos desnecessários ou perigosos. Por exemplo, verificar se um diretório existe antes de tentar acessá-lo:
[ -d /caminho ] && cd /caminhoSe o diretório não existir, o cd não é executado, evitando erro. O curto-circuito também permite encadear várias condições de forma eficiente.
Encadeamento de comandos
Encadeamento é o uso de operadores lógicos para executar múltiplos comandos em sequência, com controle de fluxo. É possível combinar && e || para criar pipelines condicionais complexos.
Exemplo: tentar criar um diretório, se falhar, tentar outro nome, e se tudo falhar, exibir erro.
mkdir dir1 || mkdir dir2 || echo "Não foi possível criar diretório"Outro exemplo: verificar se um arquivo pode ser lido e, se sim, exibir seu conteúdo; caso contrário, exibir erro.
[ -r arquivo.txt ] && cat arquivo.txt || echo "Arquivo não legível"O encadeamento pode incluir subcomandos com () para agrupar lógica:
(comando1 && comando2) || (comando3 && comando4)Isso permite construir árvores de decisão sem usar if explícito, mas cuidado com a legibilidade: para scripts longos, prefira estruturas condicionais tradicionais.
Boas práticas e observações finais
Embora os operadores lógicos sejam poderosos, evite usá-los em excesso para não prejudicar a legibilidade. Para scripts simples, eles são ótimos; para lógicas complexas, use if/then/else. Lembre-se de que o código de saída do último comando executado determina o resultado geral da expressão. Teste sempre seus scripts com diferentes cenários (sucesso e falha) para garantir o comportamento esperado.
Referências
- GNU Bash Manual: Conditional Constructs
- Advanced Bash-Scripting Guide: Operations
- man bash (Linux die.net)
- ShellCheck - shell script analysis tool
- Bash Hackers Wiki
Exercícios
- Escreva um comando que crie um arquivo chamado "teste.txt" e, se bem-sucedido, escreva "Criado com sucesso" no terminal. Se falhar, escreva "Falha ao criar".✓ Resposta:
touch teste.txt && echo "Criado com sucesso" || echo "Falha ao criar" - Usando o operador !, escreva um comando que execute "echo 'Arquivo não existe'" apenas se o arquivo "dados.txt" não existir.✓ Resposta:
! test -f dados.txt && echo "Arquivo não existe" - Explique o que acontece na execução de:
false && echo "sim" || echo "não". Justifique com o conceito de curto-circuito.✓ Resposta: O comandofalseretorna 1 (falha). O && avalia: como false falhou, o curto-circuito impede a execução de "echo sim". O resultado do && é falso (código 1). Então o || é avaliado: como o comando anterior falhou, o || executa "echo não". Portanto, a saída será "não". - Escreva um encadeamento que tente remover o arquivo "temp.txt" com rm. Se falhar (arquivo não existe), tente usar o comando
rm -f(força remoção). Se ainda falhar, exiba "Não foi possível remover".✓ Resposta:rm temp.txt || rm -f temp.txt || echo "Não foi possível remover" - Usando apenas operadores lógicos (&&, ||, !), escreva um comando que execute "echo 'Sucesso'" se o diretório "/tmp" existir e for gravável; caso contrário, execute "echo 'Falha'". Dica: use
test -detest -w.✓ Resposta:test -d /tmp && test -w /tmp && echo "Sucesso" || echo "Falha"