É possível tornar a escrita em .bash_history imediata?


125

Eu muitas vezes abertas e lotes de terminais [Agora eu tenho 7 aberto neste espaço de trabalho] e muitas vezes eu procurar historycom greppara encontrar um comando Acabo de escrever recentemente, mas eu não quero caçar o terminal e, em seguida, vá para cima e caçar mais, etc. Às vezes, meus terminais fecham sem 'saída' e tudo o que escrevi se perde [às vezes eu precisava de algo que escrevi em um terminal que foi morto].

Portanto, existe uma maneira de fazê-lo para que cada terminal grave imediatamente no .bash_history? ou pelo menos uma vez por minuto, ou algo assim?


2
Normalmente, eu uso control-ra pesquisa reversa no histórico de comandos de um bash. Mais conveniente do que a history | grepmenos que você precise de uma regex.
Peter Cordes

Respostas:


93

Uma solução simples, conforme detalhado no histórico de atualizações do Bash em tempo real .

Ele diz para colocar esses comandos na configuração .bashrc:

shopt -s histappend
PROMPT_COMMAND="history -a;$PROMPT_COMMAND"

O primeiro comando altera o .historymodo de arquivo para acrescentar. E o segundo configura o history -acomando a ser executado em cada prompt do shell. Ele -agrava imediatamente as linhas atuais / novas no arquivo de histórico.

Relacionado para zsh:


1
Bem, este tipo de obras. Eu tentei mais alguns testes e parece funcionar apenas no primeiro comando. funciona corretamente para você?
Matt

55

Tente colocar isso no seu .bashrc:

shopt -s histappend                      # append to history, don't overwrite it
export PROMPT_COMMAND="history -a; history -c; history -r; $PROMPT_COMMAND"

Crédito aqui: https://stackoverflow.com/questions/103944/real-time-history-export-amongst-bash-terminal-windows/3055135

history -climpa o histórico da sessão em execução. Isso reduzirá o contador de histórico pela quantidade de $HISTSIZE. history -rleia o conteúdo $HISTFILEe insira-o no histórico atual da sessão em execução. Isso aumentará o contador do histórico pela quantidade de linhas inseridas $HISTFILE.

Eu acho que isso significa que os comandos estão disponíveis quase que imediatamente (você tem um terminal, gravação echo 1, segundo terminal echo 2, primeiro echo 3e, pressionando a seta para baixo duas vezes, você deve ter echo 2disponível. Você deve emitir um comando em um determinado terminal para ter acesso ao que possui foi escrito.


Brilhante! Obrigado. Pergunto-me por que essas opções não estão documentadas em man history... #
1813

10
@artfulrobot: Este comando é um bashbuilt-in, portanto é descrito em man bash. Você também pode usar help history.
pabouk

2
Eu tenho o meu zsh configurado para funcionar assim: cada shell rastreia seu próprio histórico (e antes disso, o histórico combinado) e todo comando é anexado ao histórico combinado. Isso é diferente e melhor do que sempre recarregar o histórico para cada comando para cada shell, porque eu tendem a ter um "thread de trabalho" ou "job" diferente para cada terminal do shell. Eu acho que é a diferença entre isso com -re -cvs apenas ter -a.
Steven Lu

Então, o que exatamente você está usando? history -c; history -r? Eu acho que é melhor para você, seria melhor para mim apenas algumas vezes, eu geralmente uso várias conchas para fazer um trabalho, então prefiro ter a história o mais combinada possível. Na verdade, eu me importo que o comando seja gravado na história somente depois que terminar. Normalmente, quando inicio uma sessão ssh em um host e quero abrir outro enquanto o primeiro ainda está em execução, preciso digitá-lo novamente, porque ainda não foi gravado no histórico.
2525

Eu acho que nunca fiquei tempo suficiente para descobrir como fazer o bash rastrear simultaneamente threads paralelos do histórico (por base de instância do shell) enquanto escrevia o histórico imediatamente no arquivo de histórico principal. O Zsh facilita muito isso, além disso, defini uma função zsh para escrever muitos metadados sofisticados em um arquivo de histórico aprimorado da minha criação. Tornou-se bastante indispensável. De qualquer forma, o mecanismo lá é precmd () e preexec () para zsh recebem argumentos que descrevem o comando digitado. Torna-se trivial direcionar isso para arquivos. history -apode bastar
Steven Lu

38

Eu tenho um arquivo de histórico grande com cerca de 100000 entradas e as variantes que limpam a lista de histórico e leem o arquivo de histórico inteiro (usando history -ce history -r) apresentam um atraso notável (talvez 0,2 segundo) antes que o prompt seja exibido. Usar history -npara que apenas novas linhas sejam lidas do arquivo de histórico é mais rápido:

shopt -s histappend
PROMPT_COMMAND='history -a;history -n'

PROMPT_COMMAND não precisa ser exportado porque é uma variável de shell.


Brilhante! Não há mais histórico perdido quando a conexão cai!
precisa saber é

Isso é maravilhoso. Ao anexar ao arquivo e ler o arquivo, ele compartilhará o histórico em vários terminais.
23618 wisbucky

3

Uma observação para todas as outras respostas (que são basicamente a mesma coisa):

Definir PROMPT_COMMAND="history -a;$PROMPT_COMMAND"no .bashrc(ou amigos) é suficiente.

Além disso, você pode executar manualmente history -asempre que desejar "capturar instantaneamente" o histórico na sessão atual.

O comando shopt -s histappendnão é necessário porque history -asempre acrescenta novas linhas ao arquivo e nunca o substitui. Além disso, pelo menos a partir do Bash 4, histappendé o comportamento padrão.


No meu mac 10.13.6, parecia que não funcionava sem o shopt -s histappend. Observe também eu adicionei-o ao meu~/.bash_profile
ubershmekel

Provavelmente, há outra configuração em algum lugar do sistema que foi desativada histappend, pois esse é o comportamento padrão. Eu procuraria, mas não tenho acesso a um Mac.
Guss
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.