30 out 2026 · linux, shell, bash · 5 min
O que é bash e por que ele ainda está em todo lugar
Bash é o interpretador de comandos que vem instalado em quase todo Linux e no macOS. Ele lê uma linha, executa e devolve o resultado. A razão de ainda estar em todo lugar é simples: é o shell padrão do sistema, e a maior parte dos scripts de instalação, backup e manutenção do mundo foi escrita para ele.
O que o bash é de verdade
Um shell faz duas coisas: lê comandos e roda programas. O bash faz isso e mais um pouco. Ele tem variáveis, laços, funções, arrays e substituição de comando. A maior parte do que você digita num terminal passa por ele antes de virar execução.
O ponto que confunde iniciante é achar que bash e sh são a mesma coisa. Não são. O sh é uma especificação (POSIX). O bash é uma implementação que tenta ser compatível, mas adiciona recursos próprios. Quando um script começa com #!/bin/sh, ele promete rodar em qualquer shell POSIX. Quando começa com #!/usr/bin/env bash, ele assume bash e pode usar tudo que o bash oferece.
Por que ele não morreu
Três motivos. Primeiro, inércia: bilhões de linhas de script já existem em bash, e ninguém vai reescrever. Segundo, o bash é o shell de login padrão na maioria das distribuições Linux, então o usuário final já o tem. Terceiro, ele resolve 95 por cento dos problemas de automação sem precisar de linguagem compilada.
O custo dessa onipresença é a portabilidade. Um script bash que usa array ou [[ ]] não roda em dash, que é o sh do Debian e do Ubuntu. É a armadilha mais comum em scripts de instalação.
Um script mínimo que roda
O script abaixo conta linhas nos arquivos .txt de um diretório. Ele tem os três elementos que um script bash sério precisa: shebang, set -euo pipefail e variáveis entre aspas.
#!/usr/bin/env bash
# checar-arquivos.sh: conta linhas nos .txt de um diretório
set -euo pipefail
DIR="${1:-.}"
if [[ ! -d "$DIR" ]]; then
echo "diretorio nao existe: $DIR" >&2
exit 1
fi
cd "$DIR"
mapfile -t arquivos < <(find . -maxdepth 1 -type f -name '*.txt' -print0 | xargs -0 -r printf '%s\n')
total=0
for f in "${arquivos[@]}"; do
linhas=$(wc -l < "$f")
total=$((total + linhas))
printf '%s: %d linhas\n' "$f" "$linhas"
done
printf 'total: %d linhas em %d arquivo(s)\n' "$total" "${#arquivos[@]}"
O set -e aborta se um comando falhar. O set -u aborta se uma variável não definida for usada. O set -o pipefail faz um pipeline falhar se qualquer parte falhar, não só a última. Juntos, os três evitam o pior bug de shell: seguir em frente depois de um erro silencioso.
As três armadilhas que esse script evita:
- Variável sem aspas.
cd $DIRquebra se o caminho tiver espaço. Sempre"$DIR". cdque falha em silêncio. Semset -e, o script continua no diretório errado. Comset -e, ele para.- Pipeline que esconde erro.
grep foo arquivo | wc -ldevolve zero mesmo se o grep falhar, a menos que existapipefail.
Para rodar: salve como checar-arquivos.sh, dê permissão com chmod +x checar-arquivos.sh e chame com ./checar-arquivos.sh /caminho/da/pasta. O jq é útil para tratar a saída quando o script alimenta outro sistema.
Como verificar
bash checar-arquivos.sh /caminho/da/pasta
Saída esperada:
./b.txt: 3 linhas
./a.txt: 2 linhas
total: 5 linhas em 2 arquivo(s)
Se você rodar o mesmo arquivo com sh, o bashismos quebram na primeira linha útil:
sh checar-arquivos.sh /caminho/da/pasta
checar-arquivos.sh: 2: set: Illegal option -o pipefail
Esse erro é a prova de que bash e sh não são a mesma coisa. A correção é chamar com bash ou reescrever sem bashismos.
Se der errado
bad interpreter: No such file or directory: o arquivo tem quebra de linha Windows (CRLF). Converta comsed -i 's/\r$//' checar-arquivos.sh.unbound variable:set -upegou uma variável não definida. Use${VAR:-}para dar valor padrão.command not foundemmapfile: você está em bash antigo (anterior ao 4.0) ou em sh. Troquemapfilepor um laçowhile read.- Script segue depois de erro: faltou
set -eou o erro aconteceu dentro de umifou laço, ondeset -enão age. Adicione|| exit 1no comando crítico.
Tabela comparativa
| Recurso | bash | sh (dash) | zsh |
|---|---|---|---|
| Arrays | sim | não | sim |
[[ ]] |
sim | não | sim |
pipefail |
sim | não | sim |
| Modo POSIX | opcional | nativo | opcional |
| Instalado por padrão | sim | sim | não |
Se o script precisa rodar em qualquer máquina, escreva para sh. Se precisa de array, aspas seguras e pipefail, escreva para bash e declare isso no shebang. O cron do jeito certo mostra um caso onde set -euo pipefail evita que um job siga depois de uma falha.
FAQ
Bash é uma linguagem de programação? É uma linguagem de comando com recursos de programação. Serve para automação e orquestração, não para aplicação com interface ou lógica complexa.
Preciso aprender bash se já sei Python? Sim, para o que Python não faz bem: colar programas existentes, manipular arquivos e rodar comandos do sistema. Python é melhor para lógica; bash é melhor para cola.
Por que meu script funciona no terminal mas falha no cron? O cron roda com PATH mínimo e shell sh. Use caminhos absolutos e shebang explícito. Veja cron do jeito certo.
Bash é lento? Para laços sobre milhares de arquivos, sim. Para chamar programas externos, a velocidade do bash não é o gargalo.
Posso usar bash em Windows?
Sim, via WSL, Git Bash ou MSYS2. O shebang e o set -euo pipefail funcionam igual.
Fontes
- GNU Bash Reference Manual, edição 5.3, consultado em 30 de outubro de 2026.
- bash(1), página de manual do Linux, consultada em 30 de outubro de 2026.