15%

Poupe 15% em todos os serviços

Teste as suas habilidades e obtenha Desconto em qualquer plano

Utilizar o código:

Skills
Começar a trabalhar
09.10.2024

O Comando `history` no Linux: Um Guia Completo para o Histórico do Bash

O comando `history` no Linux é um utilitário integrado do shell Bash que regista, exibe e gere todos os comandos executados numa sessão de terminal. Lê e escreve em `~/.bash_history`, um ficheiro de texto simples no diretório home de cada utilizador, permitindo-lhe recordar, pesquisar, re-executar e auditar comandos entre sessões sem os redigitar.

Para administradores de sistemas e utilizadores avançados, o histórico do Bash não é meramente uma funcionalidade de conveniência — é um registo de auditoria operacional, uma ferramenta de depuração e um multiplicador de produtividade. Compreender os seus mecanismos internos, variáveis de configuração e implicações de segurança distingue os utilizadores casuais dos engenheiros que extraem o máximo valor da linha de comandos.

Como o Histórico do Bash Funciona Internamente

Quando abre uma sessão de terminal, o Bash carrega o conteúdo de `~/.bash_history` para uma lista em memória. À medida que executa comandos, estes são adicionados a este buffer em memória. Quando a sessão termina normalmente (via `exit` ou `logout`), o buffer é descarregado de volta para `~/.bash_history` de acordo com as regras definidas pelas suas variáveis de ambiente.

Esta arquitetura tem uma implicação crítica: se a sua sessão terminar de forma anormal (falha de energia, desconexão SSH, `kill -9`), os comandos dessa sessão podem nunca ser escritos no disco. Esta é uma fonte comum de confusão quando os administradores perdem o rasto dos comandos executados durante uma sessão interrompida.

Duas opções do shell modificam este comportamento padrão de escrita ao sair:

  • `shopt -s histappend` — adiciona o novo histórico a `~/.bash_history` em vez de o sobrescrever. Isto é essencial em ambientes com múltiplas sessões.
  • `PROMPT_COMMAND='history -a'` — força o Bash a adicionar o último comando ao ficheiro de histórico após cada prompt, permitindo persistência em tempo real e visibilidade entre terminais.

Sem `histappend`, o último shell a fechar vence — sobrescreve o ficheiro de histórico, descartando silenciosamente as entradas de todas as outras sessões simultâneas.

Utilização Básica do Comando `history`

Exibir o Histórico Completo de Comandos

“`bash

history

“`

Apresenta uma lista numerada de comandos armazenados. O número à esquerda é o índice do histórico, utilizado para designadores de eventos.

Exibir um Número Específico de Comandos Recentes

“`bash

history 20

“`

Mostra os últimos 20 comandos. Útil quando precisa de uma visão rápida da atividade recente sem percorrer centenas de entradas.

Escrever o Histórico da Sessão Atual no Ficheiro Imediatamente

“`bash

history -w

“`

Força uma escrita imediata do buffer de histórico em memória para `~/.bash_history`. Utilize isto antes de fechar uma sessão crítica para garantir que nada se perde.

Ler o Histórico do Ficheiro para a Sessão Atual

“`bash

history -r

“`

Recarrega `~/.bash_history` para a memória da sessão atual. Útil quando pretende aceder a comandos digitados noutro terminal durante o mesmo login.

Recordar e Re-Executar Comandos

Designadores de Eventos com `!`

A sintaxe de designador de eventos do Bash permite a re-execução direta de comandos históricos por referência:

DesignadorComportamento
`!!`Re-executa o comando imediatamente anterior
`!n`Executa o comando no índice de histórico `n`
`!-n`Executa o comando `n` posições atrás da atual
`!string`Executa o comando mais recente que começa com `string`
`!?string?`Executa o comando mais recente que contém `string` em qualquer posição
`!$`Substitui pelo último argumento do comando anterior
`!*`Substitui por todos os argumentos do comando anterior

Exemplo prático — reutilizar o último argumento:

“`bash

mkdir /var/www/myproject

cd !$

“`

`!$` expande para `/var/www/myproject`, poupando-lhe a necessidade de redigitar o caminho. Esta é uma das funcionalidades mais subutilizadas e de maior valor do histórico do Bash.

Pré-visualizar antes de executar:

Adicione `:p` a qualquer designador de evento para imprimir o comando sem o executar:

“`bash

!42:p

“`

Este é um hábito de segurança crítico ao trabalhar em servidores de produção. Pré-visualize sempre comandos destrutivos antes da execução.

Designadores de Palavras para Extração de Argumentos

Para além de re-executar comandos completos, o Bash permite extrair argumentos específicos de entradas do histórico:

“`bash

!!:2 # Second word (argument) of the last command

!!:1-3 # Words 1 through 3 of the last command

!ssh:$ # Last argument of the most recent ssh command

“`

Este nível de granularidade é inestimável na construção de pipelines complexos ou na repetição de operações nos mesmos caminhos de ficheiros.

Atalhos de Teclado para Navegação no Histórico

AtalhoAção
`Up Arrow` / `Ctrl+P`Mover para o comando anterior
`Down Arrow` / `Ctrl+N`Mover para o próximo comando
`Ctrl+R`Pesquisa inversa incremental no histórico
`Ctrl+S`Pesquisa incremental direta (requer `stty -ixon`)
`Alt+.`Inserir o último argumento do comando anterior
`Ctrl+G`Cancelar a pesquisa de histórico atual

Nota sobre `Ctrl+S`: Por padrão, `Ctrl+S` ativa o controlo de fluxo XON/XOFF e congela o terminal. Para ativar a pesquisa direta no histórico, adicione `stty -ixon` ao seu `~/.bashrc`.

Pesquisa Inversa com `Ctrl+R`

“`

(reverse-i-search)`git': git commit -am "fix: resolve race condition"

“`

Digite uma substring e o Bash encontra incrementalmente o comando mais recente que a contém. Prima `Ctrl+R` novamente para avançar para correspondências mais antigas. Prima `Enter` para executar, ou `Ctrl+G` para abortar sem executar nada.

Para pesquisas de histórico de grande volume, redirecione para `grep`:

“`bash

history | grep "docker run"

history | grep -E "^[[:space:]]+[0-9]+[[:space:]]+ssh"

“`

Editar e Gerir Entradas do Histórico

Eliminar uma Entrada Específica

“`bash

history -d 87

“`

Remove o comando no índice 87 da lista em memória. Para tornar isto permanente, siga com `history -w` para escrever a lista modificada de volta no disco.

Eliminar um Intervalo de Entradas

“`bash

for i in $(seq 85 90); do history -d 85; done

“`

Como a eliminação desloca os índices, elimine sempre o mesmo número de índice num ciclo em vez de o incrementar.

Limpar Todo o Histórico em Memória

“`bash

history -c

“`

Apaga o buffer de histórico da sessão atual. Isto não afeta `~/.bash_history` no disco.

Eliminar Completamente Todo o Histórico

“`bash

history -c && history -w

“`

Limpa o buffer em memória e depois escreve o buffer vazio em `~/.bash_history`, truncando efetivamente o ficheiro. Esta é a sequência correta de dois passos — usar `> ~/.bash_history` isoladamente não limpa o buffer em memória, pelo que o ficheiro pode ser repovoado ao sair da sessão.

Configurar o Histórico do Bash: Variáveis de Ambiente

Todo o comportamento do histórico é governado por variáveis de ambiente, tipicamente definidas em `~/.bashrc` (shells interativos não-login) ou `~/.bash_profile` / `~/.profile` (shells de login). As alterações entram em vigor após recarregar o ficheiro:

“`bash

source ~/.bashrc

“`

`HISTSIZE`

Controla quantos comandos são mantidos em memória durante uma sessão ativa.

“`bash

export HISTSIZE=10000

“`

Definir isto como `0` desativa completamente o histórico em memória. Definir como `-1` (no Bash 4.3+) torna-o ilimitado.

`HISTFILESIZE`

Controla o número máximo de linhas armazenadas em `~/.bash_history` no disco.

“`bash

export HISTFILESIZE=20000

“`

Quando o ficheiro excede este limite, o Bash remove as entradas mais antigas. Para ambientes sensíveis à conformidade, defina este valor como elevado e combine-o com rotação de registos.

`HISTCONTROL`

Determina as regras de filtragem para os comandos que são registados.

ValorComportamento
`ignoredups`Ignora comandos duplicados consecutivos
`ignorespace`Ignora comandos prefixados com um espaço
`ignoreboth`Combina ambos os anteriores
`erasedups`Remove todas as ocorrências anteriores de um comando antes de adicionar o novo

“`bash

export HISTCONTROL=ignoreboth

“`

Caso de uso de segurança para `ignorespace`: Prefixe qualquer comando que contenha uma palavra-passe ou segredo com um espaço para evitar que seja registado:

“`bash

mysql -u root -pSuperSecretPassword

“`

Esta é uma prática de segurança operacional amplamente utilizada em sistemas partilhados ou multiutilizador.

`HISTTIMEFORMAT`

Adiciona um carimbo de data/hora a cada entrada do histórico, armazenado como uma linha de comentário em `~/.bash_history`.

“`bash

export HISTTIMEFORMAT="%Y-%m-%d %H:%M:%S "

“`

Exemplo de saída:

“`

487 2024-11-14 09:32:17 systemctl restart nginx

488 2024-11-14 09:32:45 tail -f /var/log/nginx/error.log

“`

Os carimbos de data/hora são essenciais para a análise forense pós-incidente em ambientes de VPS Hosting e infraestrutura dedicada. Sem eles, sabe-se *o que* foi executado, mas não *quando*.

`HISTIGNORE`

Uma lista separada por dois pontos de padrões glob. Os comandos que correspondam a qualquer padrão não são guardados no histórico.

“`bash

export HISTIGNORE="ls:ll:la:cd:pwd:exit:clear:history"

“`

Isto evita que comandos triviais poluam o seu histórico e diluam os resultados de pesquisa. Também pode usar wildcards:

“`bash

export HISTIGNORE="*password*:*secret*:*token*"

“`

Esta é uma medida de defesa em profundidade — combine-a com `ignorespace` para máxima higiene de credenciais.

Variáveis de Configuração do Histórico do Bash: Tabela de Referência Completa

VariávelPadrãoFinalidade
`HISTSIZE`500–1000Comandos mantidos em memória por sessão
`HISTFILESIZE`500–2000Linhas armazenadas em `~/.bash_history`
`HISTCONTROL`(não definido)Regras de filtragem para comandos registados
`HISTTIMEFORMAT`(não definido)Formato de carimbo de data/hora adicionado às entradas
`HISTIGNORE`(não definido)Padrões glob para comandos a excluir
`HISTFILE``~/.bash_history`Caminho para o ficheiro de histórico
`histappend` (shopt)offAdicionar vs. sobrescrever ao sair da sessão

Partilhar Histórico Entre Múltiplas Sessões de Terminal

Por padrão, cada sessão do Bash mantém o seu próprio buffer de histórico isolado. Os comandos digitados no Terminal A são invisíveis para o Terminal B até que ambas as sessões fechem e o ficheiro seja escrito. Para administradores que gerem múltiplas sessões SSH simultaneamente em Servidores Dedicados, isto cria lacunas no registo operacional.

A configuração recomendada para partilha de histórico em tempo real entre sessões:

“`bash

~/.bashrc

export HISTSIZE=100000

export HISTFILESIZE=100000

export HISTCONTROL=ignoreboth

export HISTTIMEFORMAT="%Y-%m-%d %H:%M:%S "

shopt -s histappend

PROMPT_COMMAND='history -a; history -c; history -r'

“`

O que isto faz:

  • `history -a` — adiciona o último comando ao ficheiro
  • `history -c` — limpa o buffer em memória
  • `history -r` — recarrega o ficheiro para a memória

Após cada comando, cada sessão de terminal vê o histórico completo e unificado de todas as sessões ativas. A contrapartida é uma ligeira sobrecarga na execução de `PROMPT_COMMAND`, que é negligenciável na prática.

Pesquisar o Histórico de Forma Eficiente: Técnicas Avançadas

`fzf` — Pesquisa Difusa no Histórico

A ferramenta `fzf` transforma a pesquisa no histórico de uma análise linear numa interface interativa de correspondência difusa:

“`bash

Install fzf (Debian/Ubuntu)

sudo apt install fzf

Bind Ctrl+R to fzf-powered history search

Add to ~/.bashrc:

[ -f ~/.fzf.bash ] && source ~/.fzf.bash

“`

Uma vez configurado, `Ctrl+R` abre uma pesquisa difusa em ecrã completo sobre todo o seu histórico. Isto é particularmente poderoso com ficheiros de histórico grandes (mais de 10.000 entradas) onde `grep` se torna difícil de usar.

Extrair Histórico para Scripting

“`bash

Export all unique commands containing "iptables" to a script

history | grep iptables | awk '{$1=""; print $0}' | sort -u > iptables_audit.sh

“`

Este padrão é útil para reconstruir runbooks a partir de comandos ad-hoc executados durante a resposta a incidentes.

Considerações de Segurança para o Histórico do Bash

O histórico do Bash é uma ferramenta de dois gumes. Acelera fluxos de trabalho legítimos, mas também representa uma superfície de ataque significativa.

Principais riscos e mitigações:

  • Exposição de credenciais: As palavras-passe passadas como argumentos de linha de comandos (ex.: `curl -u admin:password`) são armazenadas em texto simples em `~/.bash_history`. Utilize `ignorespace`, `HISTIGNORE`, ou variáveis de ambiente em alternativa.
  • Análise forense de escalada de privilégios: Os atacantes que obtêm acesso ao shell leem rotineiramente `~/.bash_history` para compreender o ambiente, descobrir credenciais e identificar alvos de alto valor. Defina permissões restritivas: `chmod 600 ~/.bash_history`.
  • Adulteração do histórico: Um utilizador comprometido pode executar `history -c && history -w` para apagar todas as evidências. Para fins de auditoria em sistemas de produção, considere o registo de comandos baseado em `auditd` ou `syslog`, que não pode ser manipulado pelo utilizador.
  • Isolamento do histórico do root: O histórico do utilizador root é armazenado em `/root/.bash_history`. Certifique-se de que este ficheiro não é legível por todos e está incluído no âmbito de backup e auditoria.

Para ambientes que requerem auditoria rigorosa de comandos — como infraestrutura compatível com PCI-DSS ou SOC 2 — o histórico do Bash por si só é insuficiente. Combine-o com auditoria ao nível do kernel via `auditd` e envio centralizado de registos.

Histórico do Bash vs. Sistemas Alternativos de Histórico de Shell

FuncionalidadeHistórico do BashHistórico do ZshHistórico do Fish
Ficheiro de histórico padrão`~/.bash_history``~/.zsh_history``~/.local/share/fish/fish_history`
Suporte a carimbos de data/horaVia `HISTTIMEFORMAT`IntegradoIntegrado (formato YAML)
Gestão de duplicados`HISTCONTROL`Opção `HIST_IGNORE_DUPS`Deduplicação automática
Partilha entre sessõesManual (`PROMPT_COMMAND`)Opção `INC_APPEND_HISTORY`Automática (partilhado por padrão)
Interface de pesquisa`Ctrl+R` (linear)`Ctrl+R` (linear)Realce de sintaxe, sensível ao contexto
Tamanho máximo do históricoVariável `HISTFILESIZE`Variável `SAVEHIST`Sem limite rígido
Mecanismo de bloqueioNenhum (possíveis condições de corrida)Bloqueio de ficheiro suportadoSuportado por SQLite (escritas atómicas)

A principal limitação do histórico do Bash é a falta de bloqueio integrado, o que pode causar condições de corrida quando múltiplas sessões escrevem simultaneamente. O Zsh e o Fish lidam com isto de forma mais elegante ao nível do shell.

Configuração Prática para Ambientes de Produção

A seguir apresenta-se uma configuração de histórico `~/.bashrc` testada em produção, adequada para servidores Linux de produção, incluindo os que executam VPS com cPanel ou painéis de controlo personalizados:

“`bash

— Bash History Configuration —

export HISTSIZE=50000

export HISTFILESIZE=50000

export HISTCONTROL=ignoreboth:erasedups

export HISTTIMEFORMAT="%Y-%m-%d %H:%M:%S "

export HISTIGNORE="ls:ll:la:cd:pwd:exit:clear:bg:fg:jobs"

export HISTFILE=~/.bash_history

Append to history file; don't overwrite

shopt -s histappend

Save and reload history after each command

PROMPT_COMMAND='history -a; history -c; history -r'

Enable multi-line command history as single entry

shopt -s cmdhist

Store multi-line commands with embedded newlines

shopt -s lithist

“`

`cmdhist` e `lithist` merecem menção especial. Sem `cmdhist`, um comando de múltiplas linhas (como um ciclo `for` digitado interativamente) é armazenado como linhas separadas, tornando impossível a sua re-execução limpa. Com `cmdhist` ativado e `lithist` definido, toda a construção é armazenada como uma única entrada de histórico com newlines literais, preservando a sua estrutura.

Automatizar Fluxos de Trabalho Baseados no Histórico

Gerar um Relatório de Frequência de Comandos

“`bash

history | awk '{print $2}' | sort | uniq -c | sort -rn | head -20

“`

Isto revela os seus 20 comandos mais utilizados — útil para identificar candidatos a aliases ou funções de shell.

Auditar a Utilização de `sudo`

“`bash

history | grep sudo | awk '{$1=""; print $0}'

“`

Em ambientes partilhados de Painéis de Controlo VPS, isto fornece uma auditoria rápida das operações privilegiadas realizadas durante uma sessão.

Reconstruir uma Linha Temporal de Sessão

“`bash

HISTTIMEFORMAT="%Y-%m-%d %H:%M:%S " history | grep "2024-11-14"

“`

Filtra todos os comandos executados numa data específica — inestimável durante revisões pós-incidente.

Principais Conclusões Técnicas e Lista de Verificação

Antes de implementar uma configuração de histórico do Bash em qualquer ambiente, valide o seguinte:

  • `shopt -s histappend` está definido — evita a perda de histórico por sessões simultâneas a sobrescreverem-se mutuamente
  • `HISTSIZE` e `HISTFILESIZE` estão ambos configurados — definir apenas um deixa o outro no seu valor padrão, causando truncagem inesperada
  • `HISTTIMEFORMAT` está ativado — sem carimbos de data/hora, o histórico não tem valor forense
  • `HISTCONTROL=ignoreboth` está definido no mínimo — reduz o ruído e evita que comandos adjacentes a credenciais sejam registados
  • `HISTIGNORE` exclui comandos triviais — mantém uma elevada relação sinal-ruído no histórico
  • `~/.bash_history` tem `chmod 600` — impede outros utilizadores de lerem o seu histórico de comandos
  • `cmdhist` está ativado — garante que os comandos de múltiplas linhas são armazenados como unidades coerentes
  • `PROMPT_COMMAND` sincroniza o histórico em tempo real — necessário para ambientes com múltiplas sessões
  • `auditd` está implementado em paralelo — para sistemas de produção onde é necessário registo à prova de adulteração
  • As credenciais nunca são passadas como argumentos CLI — utilize variáveis de ambiente, `.netrc`, ou gestores de segredos em alternativa

Perguntas Frequentes

Por que razão o meu histórico do Bash desaparece após fechar uma sessão SSH?

Isto acontece tipicamente porque `shopt -s histappend` não está definido. Sem ele, cada sessão sobrescreve `~/.bash_history` ao sair. Se a sessão terminar de forma anormal (queda de rede, `kill -9`), a escrita nunca acontece. Defina `histappend` e `PROMPT_COMMAND='history -a'` para persistir comandos em tempo real.

Como posso evitar que as palavras-passe sejam guardadas no histórico do Bash?

Utilize duas técnicas complementares: prefixe o comando com um espaço (requer `HISTCONTROL=ignorespace` ou `ignoreboth`), e adicione padrões de comandos sensíveis a `HISTIGNORE`. Para uma higiene a longo prazo, nunca passe segredos como argumentos CLI — utilize variáveis de ambiente ou ferramentas dedicadas de gestão de segredos.

Qual é a diferença entre `HISTSIZE` e `HISTFILESIZE`?

`HISTSIZE` controla quantos comandos o Bash mantém em memória durante uma sessão ativa. `HISTFILESIZE` controla quantas linhas são retidas em `~/.bash_history` no disco. Ambos devem ser definidos explicitamente — um `HISTSIZE` grande com um `HISTFILESIZE` pequeno significa que o seu histórico em sessão é rico, mas a maior parte é descartada quando a sessão termina.

As entradas de histórico eliminadas podem ser recuperadas?

Uma vez executado `history -c && history -w`, o buffer em memória é limpo e o ficheiro é truncado — a recuperação padrão não é possível. No entanto, se o seu sistema utilizar snapshots do sistema de ficheiros ou soluções de backup, a versão anterior de `~/.bash_history` pode ser recuperável a partir de um snapshot. Esta é mais uma razão para implementar `auditd` para registo à prova de adulteração em infraestrutura crítica.

Como posso partilhar o histórico do Bash entre múltiplas sessões de terminal simultâneas?

Adicione o seguinte a `~/.bashrc`: `shopt -s histappend` e `PROMPT_COMMAND='history -a; history -c; history -r'`. Isto força cada sessão a adicionar o seu último comando ao ficheiro partilhado e a recarregar o ficheiro completo após cada prompt, dando a todos os terminais ativos uma visão unificada e em tempo real do histórico de comandos.

15%

Poupe 15% em todos os serviços

Teste as suas habilidades e obtenha Desconto em qualquer plano

Utilizar o código:

Skills
Começar a trabalhar