Shell Scripting
- Shell Scripting
Guia rápido: como criar um shell script no Linux
1) O que é um shell script?
Um shell script é um arquivo de texto com comandos do shell (geralmente Bash) executados em sequência. Serve para automatizar tarefas, backups, deploys, relatórios, etc.
2) Pré‑requisitos
- Um Linux com Bash (quase todas as distros têm por padrão)
- Um editor de texto:
nano,vim, ou um editor gráfico - Acesso ao terminal
3) Passo a passo (primeiro script)
-
Crie um arquivo, por exemplo
ola.sh:nano ola.sh -
Coloque o conteúdo básico:
#!/usr/bin/env bash
# Script de exemplo: imprime uma saudação
echo "Olá, mundo!"Shebang (
#!/usr/bin/env bash): indica ao sistema qual interpretador usar. -
Salve e saia (no
nano:Ctrl+O,Enter,Ctrl+X). -
Dê permissão de execução:
chmod +x ola.sh -
Execute:
./ola.shSe falhar com “Permissão negada”, verifique as permissões ou use
bash ola.sh.
4) Estrutura típica de um script
#!/usr/bin/env bash
set -euo pipefail
IFS=$'\n\t'
# === Metadados ===
# Nome: meu_script.sh
# Descrição: Faz X, Y, Z
# Uso: ./meu_script.sh [opções]
# Autor: Seu Nome
# Versão: 1.0.0
# === Funções auxiliares ===
log() { printf '[%s] %s\n' "$(date +'%Y-%m-%d %H:%M:%S')" "$*"; }
abort() { printf 'Erro: %s\n' "$*" >&2; exit 1; }
# === Validação de requisitos ===
command -v curl >/dev/null 2>&1 || abort "curl não encontrado"
# === Lógica principal ===
main() {
log "Iniciando…"
# Seu código aqui
log "Concluído."
}
main "$@"
Explicações:
set -euo pipefail: falha ao primeiro erro, erro de variável não definida (-u) e encadeamentos (pipefail).IFSseguro: evita surpresas com espaços em nomes de arquivos.main "$@": repassa argumentos para a função principal.
5) Variáveis e argumentos
-
Definição:
nome="Ana" -
Uso:
echo "Olá, $nome" -
Posicionais:
$0(nome do script),$1,$2, …,$#(quantos),$@(todos) -
Exemplo:
#!/usr/bin/env bash
set -euo pipefail
nome=${1:-mundo}
echo "Olá, $nome!"Uso:
./ola.sh Ana
Dica: sempre cite variáveis com aspas: "$var".
6) Leitura interativa
read -rp "Digite seu nome: " nome
printf 'Olá, %s!\n' "$nome"
7) Condicionais e testes
if [[ -f arquivo.txt ]]; then
echo "arquivo existe"
elif [[ -d arquivo.txt ]]; then
echo "é diretório"
else
echo "não existe"
fi
# Comparações numéricas
if (( 3 > 2 )); then echo "maior"; fi
# Comparações de strings
if [[ "$user" == "root" ]]; then echo "admin"; fi
8) Loops
# for sobre lista
for f in *.log; do
echo "Processando $f"
gzip -9 "$f"
done
# while lendo arquivo com segurança
while IFS= read -r linha; do
echo "$linha"
done < input.txt
9) Funções
soma() { echo $(( $1 + $2 )); }
resultado=$(soma 2 5)
echo "$resultado"
10) Entrada/saída, redirecionamento e pipes
>sobrescreve,>>acrescenta2>stderr,&>stdout+stderr- Exemplo:
comando >saida.txt 2>erros.log - Pipes:
ls -l | grep "\.sh$" | wc -l
11) Códigos de saída
0= sucesso;1..255= erros- Último status:
$? - Sair explicitamente:
exit 42
12) Depuração
set -xpara rastrear comandos- Ad-hoc:
bash -x script.sh - Logs com timestamps (ver função
logacima)
13) Tratamento de erros
set -euo pipefail
trap 'echo "Falhou na linha $LINENO" >&2' ERR
cria_dir() {
local dir=$1
[[ -d "$dir" ]] || mkdir -p "$dir"
}
14) Processamento de opções (getopts)
#!/usr/bin/env bash
set -euo pipefail
usage() {
cat <<EOF
Uso: ${0##*/} [-n NOME] [-v]
-n NOME Nome para saudar
-v Modo verboso
EOF
}
nome="mundo"; verbose=false
while getopts ":n:v" opt; do
case "$opt" in
n) nome=$OPTARG ;;
v) verbose=true ;;
:) echo "Faltou argumento para -$OPTARG" >&2; usage; exit 2 ;;
\?) echo "Opção inválida: -$OPTARG" >&2; usage; exit 2 ;;
esac
done
shift $((OPTIND-1))
$verbose && echo "Saudando…"
echo "Olá, $nome!"
15) Arrays
frutas=(maçã banana uva)
echo "Primeira: ${frutas[0]}"
for f in "${frutas[@]}"; do echo "$f"; done
16) Boas práticas rápidas
- Use
#!/usr/bin/env bash, nãosh, se usar recursos Bash set -euo pipefailem scripts não-interativos- Cite variáveis:
"$var" - Use
"${var:-default}"para valores padrão - Prefira
[[ ]]a[ ]para testes - Evite caminhos absolutos de comandos; valide com
command -v - Trate erros e use
trapquando fizer sentido - Escreva
usagee--help - Formate com
shellcheck(linter) quando possível
17) Agendamento com cron (opcional)
-
Edite o crontab:
crontab -e -
Exemplo: executar todo dia às 03:30:
30 3 * * * /caminho/para/backup.sh >> /var/log/backup.log 2>&1
18) Template reutilizável
#!/usr/bin/env bash
# shellcheck disable=SC2155
set -euo pipefail
IFS=$'\n\t'
readonly SCRIPT_NAME=${0##*/}
readonly SCRIPT_DIR=$(cd -- "${BASH_SOURCE[0]%/*}" && pwd)
usage() {
cat <<EOF
Uso: $SCRIPT_NAME [opções]
Opções:
-h, --help Mostra esta ajuda
-o ARQ Arquivo de saída (padrão: stdout)
EOF
}
out=""
parse_args() {
while [[ ${1-} ]]; do
case "$1" in
-h|--help) usage; exit 0 ;;
-o) shift; out=${1-""} ;;
*) echo "Argumento desconhecido: $1" >&2; usage; exit 2 ;;
esac
shift || true
done
}
main() {
parse_args "$@"
local msg="Olá do $SCRIPT_NAME"
if [[ -n "$out" ]]; then
printf '%s\n' "$msg" >"$out"
else
printf '%s\n' "$msg"
fi
}
main "$@"
19) Exemplo prático: compactar logs antigos
#!/usr/bin/env bash
set -euo pipefail
shopt -s nullglob
LOG_DIR=${1:-/var/log/meuapp}
DIAS=${2:-7}
find "$LOG_DIR" -type f -name '*.log' -mtime +"$DIAS" -print0 \
| xargs -0 -I{} gzip -9 {}
Uso: ./compacta_logs.sh /caminho/dos/logs 14