Introdução a shell scripting para automação

1. Fundamentos do Shell Scripting

Shell scripting é a arte de escrever sequências de comandos executados por um interpretador de shell, como Bash ou Zsh. Esses scripts permitem automatizar tarefas repetitivas, desde backups e renomeação de arquivos até deploys e monitoramento de sistemas. Um shell script transforma comandos manuais em processos consistentes, economizando tempo e reduzindo erros humanos.

A escolha do shell impacta a portabilidade do script. O Bash (Bourne Again Shell) é o padrão na maioria das distribuições Linux e no macOS. O Zsh oferece recursos avançados como correção ortográfica e temas, mas scripts escritos para Bash geralmente funcionam em Zsh com pequenos ajustes. Para máxima compatibilidade, use Bash.

A estrutura básica de um script inclui:

  • Shebang: #!/bin/bash indica qual interpretador usar.
  • Permissões: chmod +x script.sh torna o arquivo executável.
  • Execução: ./script.sh ou bash script.sh.
#!/bin/bash
# Meu primeiro script de automação
echo "Iniciando automação em $(date)"

2. Variáveis e Controle de Fluxo

Variáveis em shell scripts podem ser locais (definidas pelo usuário), de ambiente (herdadas do sistema) ou especiais (criadas pelo shell). Use VAR=valor (sem espaços) para declarar e $VAR para acessar.

#!/bin/bash
NOME="backup"
echo "Iniciando $NOME"

# Variável especial: código de saída do último comando
echo "Código de saída: $?"

Condicionais permitem decisões baseadas em testes. Use if, elif, else com operadores como -f (arquivo existe), -d (diretório) ou -eq (igualdade numérica).

#!/bin/bash
ARQUIVO="/tmp/teste.txt"
if [ -f "$ARQUIVO" ]; then
    echo "$ARQUIVO existe"
elif [ -d "$ARQUIVO" ]; then
    echo "$ARQUIVO é um diretório"
else
    echo "$ARQUIVO não encontrado"
fi

Laços de repetição automatizam operações em massa. O for itera sobre listas, while executa enquanto condição for verdadeira e until executa até que a condição se torne verdadeira.

#!/bin/bash
# Renomear arquivos .txt para .bak
for arquivo in *.txt; do
    mv "$arquivo" "${arquivo%.txt}.bak"
done

3. Manipulação de Arquivos e Diretórios

Comandos como cp, mv, rm, mkdir e ln são essenciais para automação. Use caminhos absolutos (iniciando com /) para scripts que rodam em contextos variáveis, ou relativos para scripts específicos de um projeto.

#!/bin/bash
DESTINO="/backup/$(date +%Y%m%d)"
mkdir -p "$DESTINO"
cp -r /dados/importantes "$DESTINO"
ln -s "$DESTINO" /backup/ultimo

Redirecionamento de saída (>), append (>>) e here documents permitem criar e modificar arquivos dinamicamente.

#!/bin/bash
# Gerar relatório com here document
cat << EOF > relatorio.txt
Data: $(date)
Usuário: $(whoami)
Arquivos no diretório:
$(ls -la)
EOF

4. Processamento de Texto e Expressões Regulares

grep busca padrões em arquivos, sed faz substituições e awk processa dados estruturados. Expressões regulares (regex) ampliam essas capacidades.

#!/bin/bash
# Extrair endereços IP de logs
grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' /var/log/syslog

# Substituir "antigo" por "novo" com sed
sed -i 's/antigo/novo/g' config.txt

# Calcular média de valores com awk
echo -e "10\n20\n30" | awk '{soma+=$1} END {print soma/NR}'

Comandos como cut (extrair colunas), paste (combinar arquivos) e tr (substituir caracteres) são úteis para transformar dados.

#!/bin/bash
# Converter nomes para maiúsculas
echo "joao maria pedro" | tr '[:lower:]' '[:upper:]'

# Extrair primeira coluna de um CSV
cut -d',' -f1 dados.csv

5. Automação de Tarefas com Argumentos e Funções

Argumentos de linha de comando tornam scripts flexíveis. $1, $2 etc. representam argumentos posicionais, $@ lista todos e $# conta quantos foram passados.

#!/bin/bash
if [ $# -lt 2 ]; then
    echo "Uso: $0 <origem> <destino>"
    exit 1
fi
cp -r "$1" "$2"
echo "Copiado de $1 para $2"

Funções organizam código reutilizável e evitam repetição. O escopo de variáveis em funções pode ser controlado com local.

#!/bin/bash
backup_dir() {
    local dir="$1"
    local dest="/backup/$(basename "$dir")_$(date +%Y%m%d)"
    tar -czf "$dest.tar.gz" "$dir"
    echo "Backup de $dir concluído em $dest.tar.gz"
}

backup_dir /home/usuario/documentos

getopts processa opções como -v (verbose) ou -o arquivo, permitindo scripts profissionais.

#!/bin/bash
VERBOSE=false
while getopts "vo:" opt; do
    case $opt in
        v) VERBOSE=true ;;
        o) OUTPUT="$OPTARG" ;;
        *) echo "Opção inválida"; exit 1 ;;
    esac
done

6. Integração com o Sistema e Agendamento

Scripts podem executar comandos do sistema e capturar saídas usando subshells ($(comando)). Isso permite, por exemplo, verificar uso de disco antes de um backup.

#!/bin/bash
ESPACO=$(df / | tail -1 | awk '{print $5}' | tr -d '%')
if [ "$ESPACO" -gt 90 ]; then
    echo "Alerta: disco com $ESPACO% de uso"
fi

Para agendamento, o cron executa scripts em horários definidos. Use crontab -e para editar.

# Executar backup todo dia às 2h
0 2 * * * /scripts/backup.sh

systemd timers oferecem mais controle e logs integrados. Logs e notificações podem ser enviados por e-mail ou registrados em arquivos.

#!/bin/bash
exec 2>> /var/log/meu_script.log
echo "Iniciando tarefa em $(date)"
# ... comandos ...
echo "Tarefa concluída"

7. Boas Práticas e Depuração

Scripts robustos tratam erros com trap (capturar sinais) e verificam códigos de saída ($?). Use exit 0 para sucesso e exit 1 para erro.

#!/bin/bash
set -e  # Sai ao primeiro erro
trap 'echo "Erro na linha $LINENO"; exit 1' ERR

cp /origem /destino || { echo "Falha na cópia"; exit 1; }

Depuração com set -x mostra cada comando executado, set -e interrompe ao primeiro erro e bash -n verifica sintaxe sem executar.

#!/bin/bash
set -x  # Modo debug
echo "Testando"
ls /inexistente  # Erro proposital

Documente scripts com comentários, mantenha versionamento com Git e crie testes simples.

#!/bin/bash
# test_script.sh
# Teste: verificar se backup funciona
./backup.sh /tmp/teste /tmp/destino
if [ $? -eq 0 ] && [ -f /tmp/destino/backup.tar.gz ]; then
    echo "Teste passou"
else
    echo "Teste falhou"
    exit 1
fi

Referências