Operadores lógicos são fundamentais em shell script para controlar o fluxo de execução com base no sucesso ou falha de comandos. Eles permitem tomar decisões simples sem a necessidade de estruturas condicionais complexas, tornando os scripts mais concisos e eficientes.

Nesta aula, vamos explorar os operadores && (AND), || (OR) e ! (NOT), além do conceito de curto-circuito e como encadear comandos de forma lógica. Com exemplos práticos, você aprenderá a usar esses operadores para criar scripts mais inteligentes e robustos.

&& e ||

Os operadores && e || são usados para combinar comandos de forma condicional. O operador && executa o próximo comando apenas se o anterior for bem-sucedido (código de saída 0). Já o operador || executa o próximo comando apenas se o anterior falhar (código de saída diferente de 0).

Exemplo prático: criar um diretório e, se bem-sucedido, entrar nele.

mkdir nova_pasta && cd nova_pasta

Se o mkdir falhar (por exemplo, diretório já existe), o cd não será executado. Com ||, podemos executar uma ação alternativa em caso de falha:

mkdir nova_pasta || echo "Falha ao criar diretório"

Esses operadores podem ser combinados para criar cadeias lógicas mais complexas.

! (negação)

O operador ! inverte o código de saída de um comando: se o comando retorna 0 (sucesso), ! faz com que seja tratado como falha (código 1), e vice-versa. É útil para executar comandos quando uma condição não é satisfeita.

Exemplo: verificar se um arquivo não existe e, se não existir, criá-lo.

if ! ls arquivo.txt &>/dev/null; then
    touch arquivo.txt
fi

Ou de forma mais concisa com ||:

ls arquivo.txt &>/dev/null || touch arquivo.txt

O operador ! também pode ser usado em testes com [ ]:

if [ ! -f "arquivo.txt" ]; then
    echo "Arquivo não existe"
fi

Curto-circuito

O curto-circuito é uma propriedade dos operadores && e || que interrompe a avaliação assim que o resultado é determinado. No &&, se o primeiro comando falhar, o segundo não é executado. No ||, se o primeiro comando for bem-sucedido, o segundo não é executado. Isso evita trabalho desnecessário e possíveis erros.

Exemplo: verificar se um diretório existe e listar seu conteúdo. Se o diretório não existir, o ls não será executado:

[ -d "meu_diretorio" ] && ls meu_diretorio

Se o diretório não existir, o teste falha e o ls é ignorado, evitando uma mensagem de erro. O curto-circuito é uma ferramenta poderosa para escrever scripts mais seguros e eficientes.

Encadeamento de comandos

É possível encadear vários comandos usando && e || para criar sequências lógicas. Por exemplo, podemos executar uma série de comandos que dependem do sucesso do anterior:

comando1 && comando2 && comando3 || echo "Algo falhou"

Nesse caso, se todos os comandos forem bem-sucedidos, a mensagem de erro não é exibida. Se algum falhar, a cadeia é interrompida e a mensagem é mostrada. Podemos também usar parênteses para agrupar comandos e controlar a precedência:

(comando1 && comando2) || (comando3 && comando4)

Isso permite criar lógicas mais complexas de forma legível. Lembre-se de que o código de saída do último comando executado determina o resultado geral.

Boas práticas

Ao usar operadores lógicos, evite encadeamentos muito longos que dificultam a leitura. Prefira quebrar em linhas com \ ou usar estruturas if para maior clareza. Sempre teste os códigos de saída e lembre-se de que o curto-circuito pode ocultar erros se não for bem compreendido. Use set -e para abortar o script em caso de falha, mas com cuidado.

Referências

Exercícios

  1. Crie um comando que tente criar um diretório chamado 'teste' e, se bem-sucedido, entre nele. Use operadores lógicos.

    ✓ Resposta:
    mkdir teste && cd teste
  2. Escreva um comando que exiba 'Arquivo existe' se o arquivo 'dados.txt' existir, ou 'Arquivo não existe' caso contrário. Use operadores lógicos.

    ✓ Resposta:
    [ -f dados.txt ] && echo 'Arquivo existe' || echo 'Arquivo não existe'
  3. Explique o que acontece no seguinte comando: false && echo "Isso não será exibido" || echo "Isso será exibido".

    ✓ Resposta: O comando false retorna código 1 (falha). Como && exige sucesso, o echo após && não é executado. Então o || é avaliado, e como o comando anterior (false) falhou, o echo após || é executado, exibindo 'Isso será exibido'.
  4. Crie um comando que execute comando1 e, se falhar, execute comando2. Se ambos falharem, exiba 'Ambos falharam'.

    ✓ Resposta:
    comando1 || comando2 || echo 'Ambos falharam'
  5. Como você usaria o operador ! para testar se uma variável $nome não está vazia? Escreva um comando que exiba 'Variável vazia' se $nome estiver vazia.

    ✓ Resposta:
    [ ! -z "$nome" ] || echo 'Variável vazia'
    Ou usando -z diretamente: [ -z "$nome" ] && echo 'Variável vazia'.