Linux / Comando history do Bash: buscar, reutilizar e gerenciar comandos

O comando history no Bash mostra os comandos anteriores guardados pelo shell atual, com os respectivos números, sendo usado para pesquisar, reexecutar, excluir itens ou sincronizar com o arquivo de histórico. Para ver apenas os 20 comandos mais recentes, use history 20; para pesquisar uma string específica, use history | grep 'termo de busca'; e para encontrar comandos rapidamente enquanto digita, use Ctrl+r.

history é um comando interno do Bash (builtin), executado pelo próprio interpretador de comandos. A explicação neste artigo é baseada no Bash, e outros shells como Zsh ou Fish podem ter arquivos de histórico e configurações diferentes.

O que é o comando history?

O Bash armazena os comandos inseridos pelo usuário em um shell interativo em uma lista de histórico na memória. history é um comando que permite visualizar e editar essa lista e ler ou escrever o arquivo de histórico indicado por HISTFILE.

O arquivo de histórico padrão geralmente é ~/.bash_history. Ao iniciar uma sessão interativa, o Bash lê esse arquivo para criar a lista de histórico na memória. Ao encerrar normalmente, grava o histórico conforme as opções e os limites configurados. O comportamento detalhado pode ser encontrado no manual dos recursos de histórico do Bash.

O histórico de comandos é um recurso de conveniência, não um registro de auditoria de segurança. Os usuários podem excluir entradas e, se o shell encerrar de forma anormal ou a gravação do histórico estiver desativada, ele pode não ser salvo.

Uso básico

Executar sem opções imprimirá o histórico da sessão atual do Bash com números.

history

Um exemplo de saída é mostrado abaixo. Os números são ilustrativos e não comprovam que os comandos foram concluídos com sucesso; eles identificam entradas do histórico.

  241  apt update
  242  systemctl status ssh
  243  journalctl -u ssh
  244  history

Para visualizar apenas uma parte recente do histórico, como as últimas 20 entradas, especifique um número.

history 20
Formato Função Pontos a observar
history n Exibir as últimas n entradas Baseia-se na lista de memória do shell atual.
history -c Excluir toda a lista de registros atual O estado de outras sessões de shell e arquivos deve ser considerado separadamente.
history -d number Excluir o item especificado Primeiro, verifique se o número a ser excluído está correto.
history -a Adicionar novos itens desta sessão ao final do arquivo HISTFILE deve ser definido.
history -n Adicionar novas entradas do arquivo à lista atual Útil ao importar registros adicionados em outra sessão.
history -r Adicionar todo o arquivo de histórico à lista atual Pode duplicar entradas que já existem.
history -w Sobrescrever o arquivo de histórico com a lista atual Se múltiplos terminais estiverem abertos, isso pode afetar o histórico de outras sessões.
history -p expression Exibir apenas o resultado da expansão do histórico É útil para verificar o resultado expandido do ! antes da execução.
history -s command Adicionar ao histórico sem executar o comando O texto passa a ser a última entrada; no uso interativo normal, substitui a própria chamada de history -s no histórico.

Para as definições exatas e os códigos de retorno de cada opção, consulte o manual dos comandos internos de histórico do Bash.

Pesquisando comandos anteriores

Filtrando a lista com grep

Se você quiser ver apenas as linhas no histórico que contêm uma string específica, use grep com o operador de canalização (pipe) |, que encaminha a saída de um comando para o próximo.

history | grep 'systemctl'

Para ignorar maiúsculas e minúsculas, use grep -i.

history | grep -i 'nginx'

Este método é conveniente para verificar resultados, mas o comando de pesquisa atual incluído na saída também pode aparecer nos resultados.

Pesquisando enquanto digita com Ctrl+r

Se o Bash estiver usando o modo de edição Emacs, padrão do Readline, você pode realizar uma busca incremental reversa de comandos anteriores com Ctrl+r. Cada vez que você digita um caractere para buscar, a entrada correspondente mais recente é exibida, e pressionar Ctrl+r novamente passa para a próxima correspondência mais antiga.

  • Enter: Executa o comando exibido.
  • Teclas de seta para esquerda/direita: Conclui a busca e edita o comando.
  • Ctrl+g: Cancela a busca e retorna à entrada original.

É uma prática segura finalizar a busca usando as teclas de seta pouco antes da execução para revisar o comando e seus argumentos. O método de busca é explicado na documentação do GNU Readline sobre pesquisa no histórico de comandos.

Como reexecutar um comando anterior

Expansão do histórico com pontos de exclamação

No Bash interativo, você pode usar a expansão de histórico começando com ! para recuperar comandos anteriores.

Expressão Significado Exemplo
!! Comando anterior sudo !! acrescenta sudo antes do comando anterior. O espaço entre sudo e !! é necessário.
!125 Comando com número de histórico 125 Você pode verificar o número a partir da saída de history.
!-3 O terceiro comando anterior da posição atual Selecione comandos recentes por posição relativa.
!ssh O comando mais recente que começa com ssh Se houver muitos comandos com o mesmo prefixo, um item inesperado pode ser selecionado.
!?nginx? O comando mais recente que contém nginx Pesquisar por uma string no meio do comando.
^old^new^ Substitua a primeira string correspondente do comando anterior e execute É usado para corrigir erros de digitação curtos e executar novamente.

A expansão do histórico está habilitada por padrão no Bash interativo, mas não é realizada por padrão em scripts de shell não interativos. Para a sintaxe detalhada, consulte o manual de expansão do histórico do Bash.

Confira a expansão antes de executar

!number e !string podem executar o comando encontrado imediatamente, então tenha cuidado especial se houver comandos de exclusão, alteração de permissão ou desligamento do sistema no histórico. Se você passar a expressão para history -p entre aspas simples, poderá verificar o resultado da expansão sem executá-lo.

history -p '!!'
history -p '!ssh'

No Bash usando Readline, configurar a seguinte opção permite que o resultado da expansão do histórico seja exibido primeiro no buffer de edição sem execução imediata.

shopt -s histverify

Quando há várias sessões de terminal, onde os números podem mudar facilmente, muitas vezes é mais seguro pesquisar com Ctrl+r, verificar o conteúdo e então executar.

Excluir histórico de comandos

Excluir uma entrada específica

Primeiro, verifique o número com history e depois exclua a entrada correspondente da lista de histórico da memória usando a opção -d.

history -d 125

Os números abaixo são exemplos: confira primeiro as entradas da sua sessão. Se o Bash atual suportar exclusão por intervalo, você também pode especificar os números inicial e final. Consulte help history para verificar as opções da versão instalada.

history -d 120-125

Para refletir os resultados da exclusão no arquivo de histórico atual, você pode verificar a lista e, em seguida, executar o history -w. No entanto, esteja ciente de que outras sessões de terminal podem, posteriormente, gravar o histórico anterior de volta no arquivo ao saírem, então certifique-se de que múltiplas sessões não estejam abertas.

Excluir toda a lista atual

A opção -c limpa todas as entradas na lista de histórico na memória do shell atual.

history -c

Para atualizar o arquivo de histórico para corresponder à lista atual, você deve entender como o history -w funciona antes de usá-lo. A exclusão do histórico apenas afeta o histórico do shell e não remove logs do sistema, logs de auditoria, backups ou histórico de outros terminais.

Arquivo de histórico e várias sessões de terminal

O Bash possui uma lista de histórico de memória separada para cada shell em execução. Por padrão, comandos executados em outro terminal podem não aparecer imediatamente no history do terminal atual.

Comando Comportamento entre o arquivo de histórico e a sessão atual
history -a Anexa ao final do arquivo o novo histórico da sessão atual que ainda não foi salvo no arquivo.
history -n Adiciona novas linhas do arquivo de histórico que a sessão atual ainda não leu à lista de memória.
history -r Anexa todo o conteúdo do arquivo de histórico ao final da lista de memória atual.
history -w Sobrescreve o arquivo de histórico com toda a lista de memória atual.

Para importar os novos comandos de outro terminal, execute history -a no terminal de origem e history -n no terminal de destino. Ambos devem usar o mesmo arquivo HISTFILE. O bloco abaixo reúne as duas operações para referência; cada uma deve ser executada na sessão correspondente.

history -a
history -n

Você pode usar a opção histappend para adicionar novas entradas em vez de sobrescrever o arquivo de histórico quando o shell é encerrado.

shopt -s histappend

Para continuar usando esta configuração, adicione-a ao ~/.bashrc do usuário. Também existe uma forma de configurar PROMPT_COMMAND para sincronizar automaticamente em cada prompt a partir de múltiplos terminais, mas você não deve sobrescrevê-lo sem verificar o valor atual, pois configurações ou programas existentes podem estar usando esta variável.

Variáveis do Bash relacionadas ao histórico

Variável Função
HISTFILE O caminho para o arquivo onde o histórico é armazenado. O valor padrão comum é ~/.bash_history.
HISTSIZE O número máximo de comandos a manter na lista de histórico de memória do shell atual.
HISTFILESIZE Limita o tamanho máximo do arquivo de histórico em termos de linhas.
HISTCONTROL Define regras de armazenamento, como não registrar comandos que começam com um espaço ou comandos duplicados consecutivos.
HISTIGNORE Especifique padrões de comandos a serem excluídos do registro, separados por dois pontos.
HISTTIMEFORMAT Especifique o formato de data e hora para exibição na saída history.

Por exemplo, as seguintes configurações mantêm até 5.000 comandos na memória e um limite de 10.000 linhas no arquivo de histórico, reduzem comandos que começam com um espaço e comandos duplicados, e exibem data e hora.

HISTSIZE=5000
HISTFILESIZE=10000
HISTCONTROL=ignoreboth:erasedups
HISTTIMEFORMAT='%F %T '
shopt -s histappend

Para manter a configuração, copie-a para o ~/.bashrc do seu usuário, preservando as demais configurações. Abra uma nova sessão do Bash ou recarregue o arquivo:

source ~/.bashrc

HISTCONTROL=ignoreboth aplica tanto o ignorespace quanto o ignoredups. erasedups remove entradas anteriores idênticas aos novos comandos da lista de histórico. O limite do arquivo é expresso em linhas e não deve ser interpretado como garantia do mesmo número de comandos. Ativar HISTTIMEFORMAT também não recupera horários reais que não foram armazenados para comandos antigos. Regras detalhadas para cada variável podem ser encontradas no manual das variáveis do Bash.

Histórico de comandos e segurança

Se você inserir senhas, chaves de API, tokens ou conteúdo de chaves privadas como argumentos de linha de comando, eles podem ser expostos não apenas no histórico do shell, mas também nas informações de processos em execução ou em outros registros. Para informações sensíveis, é recomendável não inseri-las diretamente na linha de comando, mas usar a entrada padrão fornecida pelo programa, um repositório seguro de credenciais ou um arquivo de configuração com acesso restrito.

Se ignorespace estiver definido em HISTCONTROL, comandos que começam com um espaço podem ser excluídos do histórico. No entanto, a exclusão depende de essa configuração estar ativa e não impede outros registros. Por isso, não a use como única proteção para informações sensíveis.

printf '%s\n' "$HISTCONTROL"
printf '%s\n' "$HISTFILE"

Mesmo que você exclua entradas com history -d ou history -c, as mesmas informações podem permanecer em outras sessões de shell, backups, logs de auditoria e logs de aplicativos. Se as credenciais forem expostas, não apenas exclua o histórico; você deve invalidar a senha ou token afetado e emitir um novo.

Problemas comuns

Os comandos mais recentes de outro terminal não são visíveis

Cada sessão do Bash usa uma lista de memória independente. Após executar history -a no terminal onde os comandos foram executados, tente executar history -n no terminal que você deseja verificar. A longo prazo, você pode revisar histappend e as configurações de inicialização do shell.

O histórico desapareceu após o fechamento do terminal

Confira se HISTFILE está vazio, se o arquivo permite gravação e se HISTSIZE ou HISTFILESIZE foi definido como 0. Um limite zero pode impedir que os registros sejam mantidos. Se o shell foi encerrado à força, talvez não tenha gravado o histórico na saída.

Os números do histórico mudaram

Os números do histórico não são identificadores fixos, mas a posição na lista de memória atual. Se você excluir entradas ou recarregar o arquivo para mesclar o histórico de outra sessão, os números podem mudar. É mais seguro pesquisar e verificar o conteúdo do comando em vez de lembrar e executar números antigos.

As mesmas configurações podem ser usadas no Zsh ou Fish?

Essas configurações não podem ser aplicadas diretamente. Mesmo que exista um recurso chamado history, as variáveis, os arquivos e a sincronização diferem entre shells. printf '%s\n' "$SHELL" costuma indicar o shell de login configurado, mas não comprova qual interpretador está ativo agora. No Bash, consulte printf '%s\n' "$BASH_VERSION" para ver a versão e use a documentação do shell efetivamente em execução.

Resumo

history no Bash pode ser usado não apenas para visualizar comandos anteriores, mas também para excluir entradas específicas, ler/gravar o arquivo de histórico e sincronizar entre sessões. Para pesquisas do dia a dia, history | grep e Ctrl+r são convenientes, e ao reexecutar usando a expansão de histórico, é necessário primeiro verificar o conteúdo do comando.

Para alterar a quantidade e o método de armazenamento de registros, revise HISTSIZE, HISTFILESIZE, HISTCONTROL, HISTTIMEFORMAT e histappend juntos. Os propósitos de outros comandos podem ser encontrados por tarefa na lista de comandos do Linux (em inglês).