Tutorial

Script bash para iniciantes: primeiro script, variáveis, condições, laços e cron

Atualizado: · Skillaria.Top

Um script bash é um arquivo de texto com comandos do shell que começa com a linha #!/bin/bash, recebe permissão de execução com chmod +x e é executado como ./script.sh. Nos scripts são usados variáveis, argumentos $1 e $2, condições if e laços for e while; a execução periódica é configurada com crontab -e.

Um script bash é um arquivo de texto comum com comandos que você digitaria no terminal, um por um. O script começa com a linha shebang #!/bin/bash, recebe a permissão de execução com chmod +x e é iniciado com ./script.sh. Este guia é um script bash para iniciantes do início ao fim: da primeira linha até a execução agendada, passando por variáveis, argumentos, condições, laços, tratamento de erros e cron.

Seu primeiro script bash em um minuto

Crie o arquivo com qualquer editor, por exemplo o nano:

nano hello.sh
#!/bin/bash
# Primeiro script: saudação e algumas informações do sistema
echo "Olá, $USER!"
echo "Hoje é: $(date +%Y-%m-%d)"
echo "Você está em: $(pwd)"

Salve (Ctrl+O, Enter, Ctrl+X), dê a permissão de execução e rode:

$ chmod +x hello.sh
$ ./hello.sh
Olá, alice!
Hoje é: 2026-10-12
Você está em: /home/alice

Linhas que começam com # são comentários. O trecho $(comando) insere a saída de um comando diretamente na string.

Shebang: para que serve a primeira linha

A linha #!/bin/bash diz ao sistema qual interpretador deve executar o arquivo. Sem ela, o script roda no shell que estiver disponível, e em alguns sistemas o /bin/sh não é o bash, e sim o dash, mais simples, em que parte das construções não funciona.

Também é comum a forma #!/usr/bin/env bash: ela procura o bash no PATH, o que ajuda quando o bash não está instalado em /bin.

Como executar o script e por que ./

Há duas formas:

  • ./hello.sh: exige a linha shebang e a permissão de execução x. O prefixo ./ é obrigatório porque o diretório atual não está no PATH.
  • bash hello.sh: não exige permissão de execução, pois o interpretador é indicado explicitamente.

Se você vir command not found sem o ./, ou Permission denied sem o chmod +x, são exatamente essas duas causas. Para chamar seus scripts pelo nome de qualquer lugar, coloque-os em ~/bin ou em /usr/local/bin.

Variáveis

Uma variável é atribuída sem espaços em volta do = e lida com o $:

#!/bin/bash
name="backup"
dir="/var/backups"
today=$(date +%F)

echo "Arquivo: ${dir}/${name}-${today}.tar.gz"

As chaves separam o nome da variável do texto que vem depois. Escrever name = "backup" com espaços é um erro: o bash tentaria executar um comando chamado name.

As aspas importam

Dentro de aspas duplas as variáveis são substituídas; dentro de aspas simples, não. As variáveis quase sempre devem ser colocadas entre aspas duplas, senão um nome de arquivo com espaço será dividido em dois argumentos.

file="meu relatório.txt"
rm $file      # erro: tentará apagar «meu» e «relatório.txt»
rm "$file"    # correto
echo '$HOME'  # imprime $HOME literalmente
echo "$HOME"  # imprime /home/alice

Variáveis de ambiente

Variáveis como $HOME, $USER e $PATH são definidas pelo sistema. Uma variável sua pode ser passada aos processos filhos com export. Configurações de ambiente permanentes ficam em ~/.bashrc ou ~/.profile.

Argumentos do script

Os valores passados na execução ficam disponíveis em $1, $2 e assim por diante.

VariávelConteúdo
$0nome do script
$1, $2…primeiro, segundo argumento
$#quantidade de argumentos
"$@"todos os argumentos, um a um
$?código de saída do último comando
$$PID do script atual
#!/bin/bash
echo "O script $0 recebeu $# argumento(s)"
echo "Primeiro: $1"
$ ./args.sh nginx 80
O script ./args.sh recebeu 2 argumento(s)
Primeiro: nginx

A entrada do usuário é lida com read: read -p "Digite o nome: " name.

Condições com if

Cada comando devolve um código de saída: 0 significa sucesso, qualquer outro valor significa erro. O if verifica exatamente esse código. Para comparações usa-se normalmente [[ ... ]], e os espaços dentro dos colchetes são obrigatórios.

#!/bin/bash
if [[ $# -eq 0 ]]; then
    echo "Uso: $0 <diretório>"
    exit 1
fi

if [[ -d "$1" ]]; then
    echo "O diretório $1 existe"
elif [[ -f "$1" ]]; then
    echo "$1 é um arquivo, e não um diretório"
else
    echo "$1 não encontrado"
fi
TesteSignificado
-f fileo arquivo comum existe
-d diro diretório existe
-e patho caminho existe
-x fileo arquivo é executável
-z "$var" / -n "$var"a string está vazia / não está vazia
"$a" == "$b", !=comparação de strings
-eq -ne -lt -le -gt -gecomparação de números

Também é possível testar diretamente qualquer comando:

if systemctl is-active --quiet nginx; then
    echo "nginx está rodando"
else
    echo "nginx está parado"
fi

Para muitas opções, o case é mais conveniente:

case "$1" in
    start)   echo "Iniciando" ;;
    stop)    echo "Parando" ;;
    *)       echo "Comando desconhecido: $1"; exit 1 ;;
esac

Laços for e while

for: percorrer uma lista

for host in web1 web2 db1; do
    echo "Verificando $host"
    ping -c 1 -W 1 "$host" > /dev/null && echo "  disponível" || echo "  indisponível"
done

for file in /var/log/*.log; do
    echo "$file: $(wc -l < "$file") linhas"
done

for i in {1..5}; do
    echo "Tentativa $i"
done

while: enquanto a condição for verdadeira

O exemplo clássico é ler um arquivo linha por linha:

while read -r user; do
    echo "Usuário: $user"
done < users.txt

E esperar que um serviço suba:

count=0
until curl -sf http://localhost:8080/health > /dev/null; do
    count=$((count + 1))
    if [[ $count -ge 10 ]]; then
        echo "O serviço não subiu"
        exit 1
    fi
    sleep 3
done
echo "Serviço pronto"

A aritmética no bash usa parênteses duplos: $((a + b)). Ela trabalha apenas com números inteiros.

Funções

Código repetido pode ser colocado em funções. Dentro da função valem os mesmos argumentos $1, $2, e o local impede que a variável escape para fora dela.

log() {
    local level="$1"; shift
    echo "$(date '+%F %T') [$level] $*"
}

log INFO "Iniciando o backup"
log ERROR "Sem espaço em disco"

Tratamento de erros: set -euo pipefail

Por padrão, o bash continua a execução depois de um comando falhar, e o script de backup pode terminar «com sucesso» sem ter copiado nada. Por isso é comum colocar um modo estrito no início dos scripts:

#!/bin/bash
set -euo pipefail
  • -e: parar no primeiro erro.
  • -u: tratar como erro o uso de uma variável não declarada (protege contra rm -rf "$DIR/" com DIR vazio).
  • -o pipefail: considerar o pipeline com falha se qualquer parte dele falhar.

Para depurar, execute o script com bash -x script.sh: o bash imprime cada comando antes de executá-lo. Para encontrar erros comuns antes de rodar, a ferramenta shellcheck ajuda bastante.

Exemplo prático: script de backup

#!/bin/bash
set -euo pipefail

SRC="${1:-/var/www}"
DST="/var/backups/site"
KEEP_DAYS=7
STAMP=$(date +%F_%H-%M)

mkdir -p "$DST"
tar -czf "$DST/site-$STAMP.tar.gz" -C "$(dirname "$SRC")" "$(basename "$SRC")"
echo "Arquivo criado: $DST/site-$STAMP.tar.gz"

# apaga os arquivos com mais de KEEP_DAYS dias
find "$DST" -name "site-*.tar.gz" -mtime +"$KEEP_DAYS" -delete

A construção ${1:-/var/www} significa «use o primeiro argumento; se ele não existir, use /var/www». Salve o script como /usr/local/bin/backup-site.sh e torne-o executável: sudo chmod +x /usr/local/bin/backup-site.sh.

Execução agendada: cron

O cron é o serviço que executa comandos em horários definidos. As tarefas do usuário são editadas com crontab -e e listadas com crontab -l; as do root, com sudo crontab -e.

Cada linha de tarefa tem cinco campos de tempo seguidos do comando:

# minuto hora dia_do_mês mês dia_da_semana comando
30 2 * * * /usr/local/bin/backup-site.sh >> /var/log/backup.log 2>&1
AgendamentoQuando executa
*/5 * * * *a cada 5 minutos
0 * * * *no início de cada hora
30 2 * * *todo dia às 02:30
0 9 * * 1-5dias úteis às 09:00
0 3 1 * *no dia 1 de cada mês às 03:00
@rebootuma vez após a inicialização

Por que o script funciona à mão, mas não no cron

  • Ambiente diferente.O cron roda com um PATH mínimo e sem ler o seu ~/.bashrc. Use caminhos completos para comandos e arquivos, ou defina o PATH no início do crontab.
  • Diretório atual diferente.A tarefa começa no diretório pessoal, e não onde está o script. Use caminhos absolutos.
  • O caractere %.No crontab, o % significa quebra de linha, então date +%F escrito diretamente na linha precisa ser escapado como \%. Mais simples é colocar o comando dentro do script.
  • Saída perdida.Redirecione a saída para um log (>> file 2>&1), senão os erros não aparecem. As execuções do cron podem ser vistas em journalctl -u cron (nos sistemas RHEL o serviço se chama crond).

Em sistemas com systemd, é possível usar temporizadores do systemd no lugar do cron: eles gravam a saída no journal e conseguem recuperar execuções perdidas.

Conclusão

Um script bash para iniciantes é um arquivo com a linha #!/bin/bash, com permissão de execução e uma sequência de comandos. Coloque as variáveis entre aspas, verifique os argumentos com if, use os laços for e while e ative o modo estrito set -euo pipefail. Assim você tem uma ferramenta de automação confiável, que o cron pode executar no horário definido. Scripts bash, ambiente e cron são explicados com prática no curso de Linux.

Perguntas frequentes

Qual a diferença entre bash e sh?

O sh é o shell padrão POSIX, e o bash é uma versão estendida dele, com vetores, colchetes duplos e outros recursos. Um script que usa construções do bash deve ser executado com bash, e não com sh.

Qual extensão deve ter um script bash?

O Linux não se importa com a extensão: o interpretador é definido pela linha shebang. A extensão .sh é apenas uma convenção para indicar que o arquivo é um script.

Como passar uma senha para o script com segurança?

Não a passe como argumento, pois os argumentos aparecem para outros usuários no ps. Use uma variável de ambiente guardada em um arquivo com permissão 600, ou read -s para digitar sem exibir.

Como verificar se o script está rodando como root?

Compare o ID do usuário com zero: if [[ $EUID -ne 0 ]]; then echo "É preciso ser root"; exit 1; fi.

Como deixar o script rodando em segundo plano, sem parar ao sair do SSH?

Use nohup ./script.sh &, uma sessão do tmux ou do screen; para execução permanente, transforme o script em um serviço do systemd.

Aprenda este tema em vídeo

Este tema é abordado em profundidade, com prática, no curso “Linux: с нуля до уверенного администрирования”.

Ir para o curso