DevOps

Shell Script do Zero Já leu

5 min de leitura

Shell Script do Zero
Até aqui foram aprendidos comandos que se executam um de cada vez. Shell script é o passo seguinte: reunir esses comandos em um arquivo que pode s

Até aqui foram aprendidos comandos que se executam um de cada vez. Shell script é o passo seguinte: reunir esses comandos em um arquivo que pode ser executado sempre que necessário, passado para outros, versionado no Git e integrado a pipelines de CI/CD.

Em DevOps, scripts de shell estão em toda parte — em rotinas de backup, em scripts de inicialização de containers, em hooks de deploy, em verificações de saúde de serviços. Não é necessário dominar todas as nuances do Bash para ser produtivo. É necessário dominar o suficiente para escrever scripts claros, seguros e confiáveis.


Estrutura Básica de um Script

Todo script Bash começa com o shebang — a linha que informa ao sistema qual interpretador deve executar o arquivo:

#!/bin/bash

Um script completo e mínimo:

#!/bin/bash

echo "Iniciando verificação do sistema..."
date
whoami
echo "Verificação concluída."

Salva-se o arquivo como verificacao.sh, concede-se permissão de execução e executa-se:

chmod +x verificacao.sh
./verificacao.sh

O ./ antes do nome indica ao shell que o script está no diretório atual. Sem ele, o shell buscaria o comando nos diretórios do $PATH e não o encontraria.


Variáveis

#!/bin/bash

AMBIENTE="producao"
VERSAO="1.4.2"
DATA=$(date +%Y-%m-%d)

echo "Deploy da versão $VERSAO no ambiente $AMBIENTE"
echo "Data: $DATA"

Alguns pontos importantes sobre variáveis no Bash:

  • Não se usa espaço em torno do = na atribuição
  • Para usar o valor, coloca-se $ antes do nome
  • Para capturar a saída de um comando, usa-se $(comando)
  • Por convenção, variáveis de ambiente e constantes são escritas em maiúsculas

Parâmetros de Entrada

Scripts podem receber argumentos ao serem executados:

#!/bin/bash

AMBIENTE=$1
VERSAO=$2

echo "Fazendo deploy da versão $VERSAO no ambiente $AMBIENTE"

Executando:

./deploy.sh producao 1.4.2

As variáveis especiais para parâmetros:

$1, $2, $3   # Primeiro, segundo, terceiro argumento
$@           # Todos os argumentos
$#           # Quantidade de argumentos
$0           # Nome do próprio script

Condicionais

#!/bin/bash

AMBIENTE=$1

if [ "$AMBIENTE" == "producao" ]; then
  echo "ATENÇÃO: deploy em produção. Confirmando..."
elif [ "$AMBIENTE" == "staging" ]; then
  echo "Deploy em staging. Prosseguindo."
else
  echo "Ambiente desconhecido: $AMBIENTE"
  exit 1
fi

O exit 1 encerra o script com código de erro — fundamental em pipelines de CI/CD, que interpretam qualquer código diferente de zero como falha.

Comparações numéricas usam operadores diferentes:

if [ $NUMERO -eq 0 ]; then   # igual
if [ $NUMERO -ne 0 ]; then   # diferente
if [ $NUMERO -gt 10 ]; then  # maior que
if [ $NUMERO -lt 10 ]; then  # menor que

Laços

#!/bin/bash

# Iterando sobre uma lista
for SERVIDOR in web01 web02 web03; do
  echo "Verificando $SERVIDOR..."
  # aqui entraria um ssh para cada servidor
done

# Iterando sobre arquivos
for ARQUIVO in /var/log/*.log; do
  echo "Processando: $ARQUIVO"
  wc -l "$ARQUIVO"
done

# Loop com contador
for i in $(seq 1 5); do
  echo "Tentativa $i..."
done

Funções

Funções organizam o script e evitam repetição:

#!/bin/bash

verificar_servico() {
  local SERVICO=$1
  if systemctl is-active --quiet "$SERVICO"; then
    echo "✓ $SERVICO está rodando"
  else
    echo "✗ $SERVICO está parado"
  fi
}

verificar_servico nginx
verificar_servico postgresql
verificar_servico redis

A palavra local restringe a variável ao escopo da função — boa prática para evitar conflitos com variáveis globais.


Tratamento de Erros

Um script profissional não silencia erros — ele os trata. Três configurações essenciais para scripts robustos:

#!/bin/bash

set -e          # Interrompe o script se qualquer comando falhar
set -u          # Trata variáveis não definidas como erro
set -o pipefail # Propaga erros em pipes

echo "Script iniciado"
comando_que_pode_falhar
echo "Esta linha só executa se o comando acima teve sucesso"

O set -e é especialmente importante em scripts de deploy — se um passo falha, o script para imediatamente em vez de continuar e causar danos maiores.


Um Script Real: Verificação de Saúde do Servidor

#!/bin/bash

set -euo pipefail

LOG="/var/log/health-check.log"
DATA=$(date "+%Y-%m-%d %H:%M:%S")

log() {
  echo "[$DATA] $1" | tee -a "$LOG"
}

verificar_disco() {
  USO=$(df / | awk 'NR==2 {print $5}' | tr -d '%')
  if [ "$USO" -gt 85 ]; then
    log "ALERTA: Disco em ${USO}% de uso"
  else
    log "OK: Disco em ${USO}% de uso"
  fi
}

verificar_memoria() {
  LIVRE=$(free -m | awk 'NR==2 {print $4}')
  log "INFO: Memória livre: ${LIVRE}MB"
}

verificar_servicos() {
  for SERVICO in nginx postgresql redis; do
    if systemctl is-active --quiet "$SERVICO"; then
      log "OK: $SERVICO rodando"
    else
      log "ERRO: $SERVICO parado"
    fi
  done
}

log "=== Início da verificação ==="
verificar_disco
verificar_memoria
verificar_servicos
log "=== Verificação concluída ==="

Este script pode ser executado manualmente ou agendado via cron para rodar a cada hora. Ele registra tudo em log e pode ser integrado a sistemas de alerta.

Referências para Aprofundamento

Documentação e leitura

Boas práticas

  • ShellCheck — Ferramenta online que analisa scripts Bash e aponta erros, más práticas e problemas de portabilidade. Recomenda-se passar todo script por aqui antes de colocar em produção.
  • Google Shell Style Guide — Guia de estilo do Google para scripts shell. Define convenções de nomenclatura, formatação e estrutura que tornam scripts mais legíveis e mantíveis.

Prática

  • Exercism — Bash Track — Exercícios progressivos de Bash com feedback de mentores. Excelente para solidificar a sintaxe praticando problemas reais.
Comentários

Mais em DevOps

Trabalhando em Equipe com Git Flow
Trabalhando em Equipe com Git Flow

O Git oferece branches, mas não diz como usá-las. Em uma equipe...

GitHub Actions: Sua Primeira Automação de CI/CD
GitHub Actions: Sua Primeira Automação de CI/CD

Até aqui o repositório Git funcionou como um arquivo hist&oacut...

Docker Compose: Orquestrando Múltiplos Serviços Localmente
Docker Compose: Orquestrando Múltiplos Serviços Localmente

O artigo anterior terminou com um conjunto de comandos docker run que co...