Manual de Bash em português: guia completo do shell GNU

Última actualización: fevereiro 11, 2026
  • Bash é o shell padrão do GNU/Linux, compatível com POSIX e repleto de recursos interativos e de scripting.
  • O manual descreve em detalhe sintaxe, expansões, variáveis, arrays, redirecionamento, funções e controle de fluxo.
  • Recursos como histórico, Readline, completion programável e traps tornam o Bash uma linguagem de automação robusta.
  • Modos POSIX e restrito, além de compatibilidade configurável, ajudam a escrever scripts portáveis e seguros.

manual bash

Se você trabalha com Linux, mais cedo ou mais tarde vai trombar com o Bash, seja digitando comandos no terminal, automatizando tarefas com scripts ou simplesmente usando alguma distro que já traz esse shell como padrão. O problema é que a maioria das pessoas só arranha a superfície: aprende meia dúzia de comandos e nunca chega a entender o que o Bash realmente é capaz de fazer.

Este artigo é um mergulho pesado no “manual de Bash” em português, condensando e reorganizando o conteúdo técnico do manual oficial (bash(1)), das referências em português e de materiais complementares sobre shell scripting. A ideia é explicar, em linguagem natural e direta, como o Bash funciona por dentro: sintaxe, opções, variáveis, redirecionamento, histórico, arrays, expansão, funções, depuração, modo POSIX, modo restrito e muito mais.

O que é o Bash e por que ele é tão importante

O Bash (Bourne Again SHell) é o shell padrão da maioria das distribuições GNU/Linux, criado originalmente por Brian Fox para o projeto GNU como um substituto livre para o Bourne shell clássico (/bin/sh). Ele mistura recursos históricos do sh, acrescenta ideias do Korn shell (ksh) e do C shell (csh) e ainda adiciona um monte de melhorias próprias.

Além de ser um interpretador de comandos interativo, o Bash também é uma linguagem de script completa, usada para automatizar tarefas, escrever ferramentas de administração de sistemas, wrappers para outros programas e até “mini aplicativos” de linha de comando. Tudo isso é descrito em detalhes no manual oficial, que é enorme, mas extremamente preciso.

Do ponto de vista de padrão, o Bash mira a compatibilidade com a parte “Shell and Utilities” da especificação POSIX (IEEE 1003.1). Ele pode operar em modo POSIX estrito (o tal “posix mode”), ajustando comportamentos quando a especificação difere do que o Bash faz por padrão. Isso é crucial quando você precisa escrever scripts portáveis entre diferentes Unix.

Hoje o Bash está disponível em praticamente qualquer ambiente Unix-like: Linux, BSDs, macOS (embora versões mais novas usem zsh por padrão), além de portas para Windows, Cygwin, MSYS, WSL e outros sistemas. No universo GNU, ele é o shell “oficial”.

shell bash

Como o Bash é iniciado: login, interativo, não interativo e modo POSIX

O comportamento do Bash ao iniciar depende de como ele foi chamado: se é um shell de login, interativo, não interativo, se foi invocado como sh, se recebeu opções como --posix etc. Isso controla quais arquivos de configuração são lidos e quais variáveis são inicializadas.

Um shell de login é aquele cuja posição zero de argumento começa com - ou que foi iniciado com --login. Nessa situação, o Bash procura primeiro por /etc/profile, depois, no diretório pessoal, por ~/.bash_profile, ~/.bash_login e ~/.profile, usando o primeiro que existir e puder ser lido. Ao sair, lê ~/.bash_logout, se existir.

Um shell interativo é aquele em que a entrada padrão e o erro padrão são terminais (verificados via isatty(3)), ou quando se usa explicitamente a opção -i. Nesses casos, o Bash configura variáveis como PS1 e inclui i em $-, o que permite a scripts e arquivos de inicialização checarem se o shell é interativo.

Se o Bash é invocado sem ser de login, mas de forma interativa, ele lê apenas ~/.bashrc, exceto se for dada a opção --norc. A opção --rcfile arquivo permite usar um arquivo de inicialização alternativo em vez de ~/.bashrc.

Para shells não interativos, como scripts, o Bash não lê ~/.bashrc por padrão. Em vez disso, se a variável de ambiente BASH_ENV estiver definida, seu valor é expandido e usado como nome de um arquivo a ser lido antes de executar o script — uma forma de ter “configuração” para scripts.

terminal bash

Opções de invocação e funcionamento básico

Na chamada do Bash, podemos passar várias opções de linha de comando que ajustam o comportamento do shell. Elas também podem ser verificadas e alteradas depois via builtin set e a variável especial $-, que contém os flags ativos.

Entre as opções de invocação mais usadas estão: -c (executar uma string de comandos), -i (forçar modo interativo), -l (tornar-se shell de login), -r (shell restrito), -s (ler da entrada padrão), além de formas longas como --posix, --noprofile, --norc, --login e --version.

A opção -c é especialmente útil para scripts curtos ou para uso em outros programas: por exemplo, bash -c 'echo $HOME' executa apenas esse comando e encerra. Nesse caso, $0 é definido como o primeiro argumento após a string de comando, se fornecido.

Quando o Bash é invocado como sh, ele tenta imitar ao máximo o comportamento histórico do Bourne shell, mas ainda respeitando POSIX. Isso inclui ler arquivos de inicialização diferentes e entrar automaticamente em modo POSIX depois de ler esses arquivos.

Relacionado:  Administração de sistemas Linux: guia completo para iniciantes e profissionais

Se o shell detecta que está sendo executado com UID efetivo diferente do real e -p não foi passado, ele desabilita leitura de arquivos de inicialização, ignora certas variáveis passadas via ambiente (SHELLOPTS, BASHOPTS, CDPATH, GLOBIGNORE) e derruba o UID efetivo para o real, reforçando a segurança.

script bash

Gramática do shell: comandos simples, pipelines, listas e compostos

O coração do Bash é a forma como ele interpreta comandos. A gramática do shell define comandos simples, pipelines, listas e comandos compostos, além de funções de shell.

Um comando simples é a forma mais básica: uma sequência opcional de atribuições de variáveis, seguida de palavras separadas por espaço e redirecionamentos, terminada por um operador de controle (como ponto e vírgula, & ou quebra de linha). O primeiro token é o comando em si, os demais são argumentos; o código de saída é o status de retorno desse programa (ou 128+N se for terminado por sinal N).

Um pipeline é uma sequência de comandos encadeados com | ou |&, onde a saída padrão de um comando vai para a entrada padrão do próximo. Com |&, tanto stdout quanto stderr do comando à esquerda vão para a entrada do próximo. O status de um pipeline é o do último comando, a menos que a opção pipefail esteja ativa, caso em que o pipeline retorna o status do último comando que falhou.

Listas de comandos encadeiam pipelines usando ;, &, && e ||. && executa o segundo comando apenas se o primeiro teve sucesso (status 0); || roda o segundo somente se o primeiro falhou (status diferente de 0). & coloca o comando em background, e ; apenas separa comandos sequenciais.

Comandos compostos incluem blocos entre parênteses ou chaves, laços, condicionais, case, select, subshells, funções e construções aritméticas. Alguns exemplos: ( lista ) roda em subshell, { lista; } roda no shell atual, if/then/elif/else, for tradicional ou aritmético, while, until, case palavra in padrões ... esac e o poderoso teste condicional ], que oferece match de padrões e regex.

As funções de shell são definidas com a sintaxe nome() { comando; } ou usando a palavra reservada function. Quando chamadas, executam em contexto de shell atual, mas com novo conjunto de parâmetros posicionais. A saída de uma função é o status do último comando executado em seu corpo.

Comentários, aspas e escapes

No Bash, comentários começam com # e vão até o fim da linha, mas só são reconhecidos em shell não interativo ou quando a opção interactive_comments está habilitada em shells interativos (por padrão, está).

O shell possui quatro mecanismos de citação (quoting): caractere de escape (\), aspas simples, aspas duplas e o formato especial $'string' com escapes tipo C. Cada um deles remove ou preserva significados especiais de certos caracteres.

O backslash não citado preserva o próximo caractere literal, exceto quando ele está seguido de \n, caso em que funciona como continuação de linha (o par é descartado pela leitura). Em aspas simples, tudo é literal até outra aspa simples (não há escape dentro de aspas simples). Em aspas duplas, $, `, \ e, quando habilitado, !, continuam com significado especial.

O formato $'...' interpreta sequências como \n, \t, \xHH, \uHHHH, \UHHHHHHHH, \cX etc. Depois de expandidas, o resultado é tratado como se estivesse entre aspas simples. Já $"..." é usado para tradução de strings via gettext de acordo com locale.

Parâmetros, variáveis, posicionais e especiais

No Bash, qualquer entidade que guarda valores é chamada de parâmetro. Quando o identificador é um nome (alfanumérico começando por letra ou underscore), chamamos de variável. Parâmetros podem ter atributos (exportado, somente leitura, inteiro, nameref etc.), definidos principalmente via builtin declare.

Variáveis são atribuídas com a forma nome=valor. O valor passa por expansão de til, expansão de parâmetros, substituição de comando, expansão aritmética e remoção de aspas, mas sem divisão de palavras nem expansão de caminhos (a menos que em contextos específicos). Se a variável tem atributo inteiro, o Bash avalia valor como expressão aritmética.

Os parâmetros posicionais são $1, $2, … até $9 e além (usando ${10}, ${11}, etc.). Eles recebem os argumentos de linha de comando ou podem ser redefinidos via builtin set. $0 normalmente guarda o nome do script ou do shell invocado.

Os parâmetros especiais incluem: $*, $@, $# (quantidade de argumentos), $? (status do último comando), $- (flags ativos), $$ (PID do shell), $! (PID do último job em background), além de vários outros como OPTARG, OPTIND, UID, EUID, RANDOM, SECONDS, PIPESTATUS, FUNCNAME, arrays especiais como BASH_ARGV, BASH_LINENO, e por aí vai.

O manual descreve uma lista extensa de variáveis pré-definidas que o próprio Bash cria e mantém, como BASH, BASH_VERSION, BASH_VERSINFO, BASHOPTS, SHELLOPTS, HISTFILE, HISTSIZE, HISTCONTROL, PS1, PS4, PWD, OLDPWD, SHLVL, HOSTNAME, MACHTYPE, OSTYPE etc. Conhecer essas variáveis ajuda demais a escrever scripts robustos.

Arrays indexados e associativos

O Bash oferece arrays unidimensionais de dois tipos: indexados (por número) e associativos (por chave string). Qualquer variável pode virar array ao usar a sintaxe nome=valor. Arrays indexados começam no índice 0, a menos que você use índices negativos, que contam a partir do fim.

Relacionado:  Guia de transição do Windows para Linux sem dor de cabeça

Para declarar explicitamente um array indexado, usa-se declare -a nome; para associativo, declare -A nome. Arrays podem ser inicializados com atribuição composta: nums=(10 20 30) ou assoc=(=valor1 =valor2). No caso associativo, também dá para usar a forma assoc=( chave1 valor1 chave2 valor2 ), onde pares chave/valor se alternam.

Para acessar elementos, usamos ${nome}. Com ${nome} ou ${nome}, obtemos todos os elementos; já ${!nome} retorna os índices (para arrays indexados) ou chaves (para associativos). ${#nome} dá o número de elementos.

O builtin unset pode remover elementos individuais (unset 'arr') ou o array inteiro (unset arr). E o builtin read com -a preenche um array a partir de uma linha da entrada padrão.

Expansão: til, chaves, parâmetros, comandos, aritmética e mais

O Bash executa uma sequência específica de expansões sobre cada linha de comando: expansão de chaves, expansão de til, expansão de parâmetros/variáveis, substituição de comando, expansão aritmética, divisão de palavras, expansão de caminhos (globbing) e, por fim, remoção de aspas.

A expansão de chaves (brace expansion) gera combinações de strings usando padrões como a{b,c,d}e (vira abe ace ade) ou sequências numéricas/letras como {1..5}, {a..z}, {10..0..2}. Ela é puramente textual e ocorre antes de qualquer outra expansão.

A expansão de til substitui ~ pelo diretório home (usuário atual ou outro usuário, se escrever ~usuario), além de ~+ (valor de PWD) e ~- (valor de OLDPWD). Quando usada em atribuições (PATH=~/bin:$PATH) e em contextos específicos, o Bash faz essa expansão automaticamente.

A expansão de parâmetros é aquela com ${param} e suas variações: valores padrão (${var:-padrao}), atribuição sob demanda (${var:=padrao}), erro se vazio (${var:?msg}), substituição alternativa (${var:+outra}), substrings (${var:offset:len}), remoção de prefixos e sufixos via padrões (#, ##, %, %%), substituição de padrões (${var/pat/sub}, //, /#, /%), modificadores de maiúsculas/minúsculas (^, ^^, ,, ,,), transformações com ${var@operador} e indireção com ${!nome}.

A substituição de comando permite inserir o resultado de outro comando na linha atual, usando $(comando), o formato antigo com crases `comando` ou a forma especial ${ c comando; } que executa no ambiente atual. O Bash executa o comando em subshell (exceto nesta forma especial), captura a saída padrão (removendo quebras de linha no final) e a insere na posição.

A expansão aritmética usa a sintaxe $((expressão)). A expressão é avaliada com semântica de C, com inteiros de largura fixa, operadores como +, -, *, /, %, shift, operadores lógicos, ternário, atribuições e incremento/decremento. Variáveis aparecem sem $ e são interpretadas como números (ou 0 se vazias).

Divisão de palavras, globbing e padrões

Depois das expansões anteriores, o Bash faz a divisão de palavras (word splitting) nas expansões de parâmetros, comandos e aritmética que não estejam entre aspas. O delimitador é definido pela variável IFS (por padrão, espaço, tab e quebra de linha). Strings vazias implícitas são descartadas, mas strings vazias explicitamente citadas são preservadas.

Em seguida, vem a expansão de caminhos (pathname expansion ou globbing), em que o shell interpreta *, ? e como padrões para listar arquivos. Se não houver match, o padrão é mantido como está, a menos que nullglob ou failglob estejam ativos. Com nullglob, padrões sem correspondência somem; com failglob, o comando falha.

O Bash oferece ainda padrões estendidos quando a opção extglob está ativa: ?(lista), *(lista), +(lista), @(lista) e !(lista), que permitem expressões de “zero ou um”, “zero ou mais”, “um ou mais”, “uma entre várias” e “negação” de padrões.

No final de tudo, o shell remove os caracteres de citação (\, ', ") que sobraram sem ter sido gerados por expansões, etapa chamada de “remoção de aspas”. Isso deixa a linha pronta para ser executada.

Redirecionamento, here-docs e here-strings

Antes de executar um comando, o Bash permite redirecionar entrada, saída e descritores de arquivo. Redirecionamentos são processados da esquerda para a direita e podem usar descritores numéricos (0,1,2…) ou o formato {var} para pedir que o shell escolha um descritor ≥ 10 e o guarde naquela variável.

Alguns formatos comuns: n<arquivo (entrada), n>arquivo (saída truncada), n>>arquivo (append), &>arquivo (stdout e stderr juntos), n>&m (duplicar descritor), n<&m (duplicar entrada), n>&- (fechar descritor), n<>arquivo (leitura+escrita).

Here-documents (<<) e here-strings (<<<) são formas práticas de alimentar dados diretamente no comando. Um here-doc tem a forma <<DELIM seguido de linhas até a linha que contém apenas DELIM. Se o delimitador estiver entre aspas, o conteúdo não é expandido; se não estiver, passam por expansões normais.

O here-string <<< palavra passa o resultado de expandir palavra (mais um \n) como entrada do comando. É ótimo para mandar uma string única para comandos que leem de stdin, como grep, sed, tr etc.

Aliases, funções e escopo de variáveis

Aliases são substituições de texto aplicadas na fase de leitura dos comandos. Você cria com alias ll='ls -l' e remove com unalias ll. Eles só são expandidos para a primeira palavra de um comando simples e não recebem argumentos — se precisar de algo mais flexível, use funções.

Funções de shell são bem mais poderosas: aceitam argumentos, têm parâmetros posicionais próprios e podem ter variáveis locais. Definimos assim: minha_func() { comandos; }. Dentro da função, $1, $2 etc. são os argumentos passados, e $# indica quantos são.

Relacionado:  Guia completo de tutoriais de linguagens de programação online

O builtin local permite criar variáveis cuja visibilidade se restringe à função atual e funções que ela chama. O Bash usa escopo dinâmico: se uma função acessa uma variável não declarada como local, ela pega o valor da função que a chamou, e assim por diante, subindo na pilha até o escopo global.

O retoro de uma função é o status do último comando executado, mas você pode usar return n para forçar um valor específico (entre 0 e 255). Esse valor pode ser lido com $? imediatamente após a chamada.

Avaliação aritmética e expressões condicionais

Além da expansão aritmética $(( )), o Bash tem o comando composto (( expressão )), que executa a expressão e retorna status 0 se o resultado for diferente de zero, ou 1 caso contrário. Isso é muito usado em laços e testes numéricos.

Operadores disponíveis seguem a semântica de C: +, -, *, /, %, ** (potência), shifts, operadores relacionais (<, <=, >, >=), de igualdade (==, !=), booleanos (&&, ||, !), bit a bit (&, |, ^, ~), atribuições compostas (+=, *=, <<=…) e o operador ternário cond ? a : b.

Testes condicionais são feitos principalmente com ], e test. ] é mais moderno e seguro: não expande globbing, tem match de padrões (== e != tratam a string da direita como padrão), operador regex (=~), e suporta combinações com &&, ||, ! e parênteses sem precisar escapar tanto.

O manual lista todos os primitivos de teste para arquivos (-f, -d, -r, -x, -s, -L, -S etc.), strings (-z, -n, ==, !=, <, >) e números (-eq, -ne, -lt, -le, -gt, -ge), tanto para ] quanto para test/.

Histórico de comandos, edição de linha e completion

O Bash integra duas bibliotecas importantes: Readline (edição de linha) e History (histórico de comandos). Isso garante atalhos de teclado em estilo Emacs ou vi, navegação no histórico, busca incremental, macros de teclado e muito mais.

O histórico é persistido em disco, por padrão em ~/.bash_history, controlado pelas variáveis HISTFILE, HISTSIZE (quantos comandos ficam em memória) e HISTFILESIZE (quantos são mantidos no arquivo). Opções como histappend, cmdhist e lithist ajustam se a escrita é por append e como comandos multilinha são armazenados.

History expansion (estilo csh) permite reutilizar comandos antigos com !!, !n, !palavra, !?texto?, ^velho^novo^ e muito mais. Isso é controlado pelo shell option histexpand, pela variável histchars e por builtins como history e fc.

Readline é configurado via ~/.inputrc e pelo builtin bind. Você pode escolher o modo de edição (set -o emacs ou set -o vi), ajustar teclas de atalho, ativar bracketed paste para colar sem disparar comandos aleatórios, configurar comportamento de completion e muito mais.

O Bash também suporta completion programável via os builtins complete e compgen. Com eles, você define como argumentos de um determinado comando devem ser completados (arquivos, diretórios, opções, usuários, hosts, serviços, nomes de jobs, etc.), inclusive chamando funções de shell que geram listas dinâmicas de sugestões.

Sinais, jobs, ambiente, status de saída e modo restrito

O Bash interage de maneira intensa com sinais (SIGINT, SIGTERM, SIGQUIT, SIGHUP, SIGCHLD, etc.). Você pode definir ações para sinais usando o builtin trap, inclusive traps especiais como DEBUG, RETURN, ERR e EXIT. Em shells interativos, SIGINT (Ctrl+C) quebra loops e interrompe comandos em foreground, enquanto SIGQUIT é ignorado por padrão.

Job control é o mecanismo que permite suspender (Ctrl+Z), retomar (fg, bg) e gerenciar múltiplos processos a partir de um único terminal. O Bash associa um “job” a cada pipeline, controla grupos de processo, encaminha sinais de teclado apenas para o job em foreground e mantém uma tabela de jobs, que pode ser vista com o builtin jobs.

O ambiente de um programa é um conjunto de pares NOME=VALOR exportados pelo shell. O Bash lê as variáveis de ambiente ao iniciar, cria variáveis de shell equivalentes e usa export, declare -x, unset e atribuições na frente de comandos para controlar o que cada processo filho recebe.

O status de saída de um comando (0 para sucesso, diferente de 0 para erro) é fundamental em scripts. Ele é obtido via $? e governa o comportamento de &&, ||, set -e (errexit) e trap ERR. Alguns códigos têm significados especiais: 126 (não executável), 127 (comando não encontrado) e 128+N quando o processo morre por sinal N.

O Bash possui ainda um modo restrito (“restricted shell”), ativado com bash -r ou chamando o binário como rbash. Nesse modo, várias ações são bloqueadas: trocar de diretório, modificar variáveis como PATH e SHELL, executar comandos contendo /, usar certos redirecionamentos e comandos como exec e enable com opções perigosas. É um recurso pensado para ambientes altamente controlados.

Juntando tudo, o manual de Bash mostra que o shell vai muito além de um simples “terminal para rodar comandos”. Ele é uma linguagem poderosa, cheia de nuances, capaz de lidar com variáveis, arrays, expansões complexas, funções, debugging, jobs, sinais, histórico, completion programável e compatibilidade POSIX — e entender bem esses conceitos é o que separa quem apenas “digita comandos” de quem realmente domina o ambiente Unix.

Artículo relacionado:
Como instalar e usar o shell bash do linux no windows 10
 

Você pode estar interessado: