Onde o histórico do bash é armazenado?

95

Se eu executar history, posso ver meus últimos comandos executados.

Mas se eu fizer tail -f $HISTFILEou tail -f ~/.bash_history, eles não serão listados.

O arquivo é bloqueado, existe um local temporário ou algo semelhante?

Adionditsak
fonte

Respostas:

117

O Bash mantém a lista de comandos internamente na memória enquanto está em execução. Eles são gravados .bash_historyna saída :

Quando um shell interativo sai, as últimas linhas $ HISTSIZE são copiadas da lista de histórico para o arquivo nomeado por $ HISTFILE

Se você deseja forçar a gravação do histórico de comandos, pode usar o history -acomando, que irá:

Anexe as novas linhas do histórico (linhas do histórico inseridas desde o início da sessão atual do Bash) ao arquivo do histórico.

Há também uma -wopção:

Escreva o histórico atual no arquivo do histórico.

o que pode ser mais adequado a você, dependendo exatamente de como você usa seu histórico.

Se você deseja garantir que eles sempre sejam gravados imediatamente, você pode colocar esse comando em sua PROMPT_COMMANDvariável:

export PROMPT_COMMAND='history -a'
Michael Homer
fonte
Nota lateral: se o seu .bash_historyarquivo acidentalmente se torna propriedade da raiz, as coisas param de funcionar. Nesse caso, verifique a propriedade e use-a sudopara corrigir a propriedade, se necessário.
torek 4/07
13

(Não é uma resposta, mas não posso adicionar comentários)

Se você estiver verificando .bash_historyporque deseja excluir um comando específico (por exemplo, contendo uma senha em branco), é possível excluir diretamente a entrada na memória por history -d <entry_id>.

Por exemplo, supondo uma saída como:

$ history
926  ll
927  cd ..
928  export --password=super_secret
929  ll

e você deseja limpar a exportlinha, basta alcançá-la:

history -d 928
Eddie C.
fonte
11

O bash o mantém na memória de trabalho, o bash pode ser configurado para salvá-lo quando o bash for fechado ou após cada comando e ser carregado quando o bash for iniciado ou mediante solicitação.

Se você configurar para salvar após cada comando, considere as implicações de ter vários bash em execução ao mesmo tempo. (as linhas de comando serão intercaladas)

ctrl-alt-delor
fonte
2
O início da resposta faz parecer que o histórico está armazenado em um arquivo chamado bash, ou mesmo no bashexetable. Eu escreveria "Ele é armazenado bashna memória, ..."
Anthon
isso é realmente melhor
Anthon
5

Os comandos são salvos na memória (RAM) enquanto sua sessão está ativa. Assim que você fecha o shell, a lista de comandos é gravada .bash_historyantes do desligamento.

Assim, você não verá o histórico da sessão atual em .bash_history.

JaySo
fonte
4
O arquivo histórico é atualizado após a bashfinalização, o que não implica reinicialização (especialmente em ambientes gráficos em que você pode abrir e fechar terminais como desejar).
John WH Smith
4

Durante a execução, o histórico é mantido apenas na memória (por padrão) se:

  • set -o history (um Hin echo "$-") está definido.
  • HISTSIZE não é 0 e
  • HISTIGNORE não é *(ou algum outro padrão muito restritivo).

Se alguma das situações acima falhar, nenhum histórico será armazenado na memória e, consequentemente, nenhum histórico poderá ou será gravado no disco.

O histórico na memória é gravado no disco se:

  • HISTFILESIZE não é 0 e
  • HISTFILE não está desmarcado.

Mas somente quando o shell sai ou se os comandos history -a(acrescentar) ou history -w(gravar) são executados.

Para disparar uma gravação imediata no disco, você pode usar a variável:

 PROMPT_COMMAND='history -a'

que alinhará appendo newhistórico com o arquivo de histórico. Essas são as linhas do histórico inseridas desde o início da sessão atual do bash, mas ainda não foram anexadas ao arquivo de histórico.

Ou:

 PROMPT_COMMAND='history -w'

Para substituir o histórico no HISTFILE pela lista da memória.

Portanto, você pode remover um comando do histórico na memória:

 $ history 5
  6359  ls
  6360  cd ..
  6361  comand --private-password='^%^&$@#)!@*'
  6362  top
  6363  set +o | less
 $ history -d 6361
 $ history 5
  6359  ls
  6360  cd ..
  6361  top
  6362  set +o | less
 $ history -w

E escreva-o no disco com o último comando:

 history -w    # with `shopt -u histappend` unset
Isaac
fonte
Haveria algo errado ao colocar isso em um trabalho cron? Eu suspeito que uma grande quantidade de usuários com muito menos nomes de usuário está conectado a um servidor específico e história ainda é bastante pequeno e este é um servidor antigo, mas talvez um pouco de sessão não estão sendo fechados ...
oneindelijk