Por que aprender Bash scripting?
Um script Bash bem escrito pode automatizar dezenas de horas de trabalho manual. Deploy de aplicações, backup automatizado, provisionamento de servidores, limpeza de logs, monitoramento de serviços — tudo isso pode ser feito com scripts Shell que qualquer administrador Linux precisa saber criar.
Estrutura básica de um script
#!/bin/bash
# Shebang: informa qual interpretador usar
# Comentário — boa prática: descreva o que o script faz
# Uso: ./meu-script.sh
echo "Olá, mundo!"
# Criar e executar o script
touch meu-script.sh
chmod +x meu-script.sh
./meu-script.sh
Variáveis
#!/bin/bash
# Definindo variáveis (sem espaço ao redor do =)
NOME="Servidor Web"
PORTA=3000
DATA=$(date +%Y-%m-%d) # captura saída de comando
# Usando variáveis
echo "Servidor: $NOME na porta $PORTA"
echo "Data: $DATA"
# Variáveis de argumentos
echo "Script: $0"
echo "Primeiro argumento: $1"
echo "Segundo argumento: $2"
echo "Total de argumentos: $#"
echo "Todos os argumentos: $@"
Condicionais if/else
#!/bin/bash
ARQUIVO="/etc/nginx/nginx.conf"
if [ -f "$ARQUIVO" ]; then
echo "Nginx está instalado"
elif [ -d "/etc/apache2" ]; then
echo "Apache está instalado"
else
echo "Nenhum servidor web encontrado"
fi
# Comparações comuns
# [ -f arquivo ] — arquivo existe e é regular
# [ -d pasta ] — diretório existe
# [ -z "$var" ] — variável está vazia
# [ -n "$var" ] — variável não está vazia
# [ $a -eq $b ] — números iguais
# [ $a -gt $b ] — a maior que b
# [ "$a" = "$b" ] — strings iguais
Loops
#!/bin/bash
# For — iterar lista
for SERVICO in nginx mysql redis; do
echo "Reiniciando $SERVICO..."
systemctl restart "$SERVICO"
done
# For — iterar arquivos
for ARQUIVO in /var/log/*.log; do
echo "Log: $ARQUIVO — $(wc -l < "$ARQUIVO") linhas"
done
# While — repetir enquanto condição for verdadeira
CONTADOR=1
while [ $CONTADOR -le 5 ]; do
echo "Tentativa $CONTADOR"
CONTADOR=$((CONTADOR + 1))
done
# Until — repetir até condição ser verdadeira
until ping -c 1 google.com &>/dev/null; do
echo "Sem conectividade, aguardando..."
sleep 5
done
echo "Conectado!"
Funções
#!/bin/bash
# Definindo funções
log() {
echo "[$(date '+%H:%M:%S')] $1"
}
verificar_servico() {
local SERVICO=$1
if systemctl is-active --quiet "$SERVICO"; then
log "$SERVICO está rodando ✓"
return 0
else
log "$SERVICO está parado ✗"
return 1
fi
}
# Usando as funções
log "Iniciando verificação de serviços"
verificar_servico "nginx"
verificar_servico "mysql"
if ! verificar_servico "redis"; then
log "Tentando iniciar Redis..."
systemctl start redis
fi
Entrada do usuário e tratamento de erros
#!/bin/bash
# Sair imediatamente se qualquer comando falhar
set -e
# Tratar variáveis não definidas como erro
set -u
# Propagar erros em pipes
set -o pipefail
# Leitura de input
read -p "Digite o nome do banco de dados: " DB_NAME
read -sp "Digite a senha: " DB_PASS # -s = silent (não mostra)
echo
# Confirmação
read -p "Confirmar exclusão? [s/N]: " CONFIRMAR
if [[ "$CONFIRMAR" != "s" && "$CONFIRMAR" != "S" ]]; then
echo "Operação cancelada."
exit 0
fi
# Trap para limpeza em caso de erro
cleanup() {
echo "Erro encontrado. Fazendo rollback..."
# comandos de limpeza aqui
}
trap cleanup ERR
Script de deploy real — exemplo completo
#!/bin/bash
set -euo pipefail
APP_DIR="/var/www/minha-app"
REPO="git@github.com:empresa/minha-app.git"
LOG="/var/log/deploy.log"
log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG"; }
log "=== Iniciando deploy ==="
log "Atualizando código..."
cd "$APP_DIR"
git pull origin main
log "Instalando dependências..."
npm ci --production
log "Buildando aplicação..."
npm run build
log "Reiniciando serviço..."
systemctl restart minha-app
log "Verificando saúde..."
sleep 3
if systemctl is-active --quiet minha-app; then
log "✓ Deploy concluído com sucesso"
else
log "✗ Serviço não iniciou — verificar logs"
journalctl -u minha-app -n 20
exit 1
fi
Boas práticas: Sempre use set -euo pipefail no início de scripts de produção, coloque variáveis entre aspas ("$VAR"), use caminhos absolutos e registre tudo em log com timestamp.