Script bash para iniciantes: primeiro script, variáveis, condições, laços e cron
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çãox. O prefixo./é obrigatório porque o diretório atual não está noPATH.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ável | Conteúdo |
|---|---|
$0 | nome 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
| Teste | Significado |
|---|---|
-f file | o arquivo comum existe |
-d dir | o diretório existe |
-e path | o caminho existe |
-x file | o 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 -ge | comparaçã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 contrarm -rf "$DIR/"comDIRvazio).-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
| Agendamento | Quando executa |
|---|---|
*/5 * * * * | a cada 5 minutos |
0 * * * * | no início de cada hora |
30 2 * * * | todo dia às 02:30 |
0 9 * * 1-5 | dias úteis às 09:00 |
0 3 1 * * | no dia 1 de cada mês às 03:00 |
@reboot | uma 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
PATHmínimo e sem ler o seu~/.bashrc. Use caminhos completos para comandos e arquivos, ou defina oPATHno 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ãodate +%Fescrito 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 emjournalctl -u cron(nos sistemas RHEL o serviço se chamacrond).
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.
Este tema é abordado em profundidade, com prática, no curso “Linux: с нуля до уверенного администрирования”.
- Bash-скрипты: от команды в терминале до рабочего скрипта автоматизации
- Пакеты, окружение и первая автоматизация: apt, профиль и cron