Este é realmente um comportamento realmente interessante e confesso que subestimei a questão no começo. Mas primeiro os fatos:
1. O que funciona
A funcionalidade pode ser alcançada de várias maneiras, embora cada uma funcione de maneira um pouco diferente. Note que, em cada caso, para ter o histórico "transferido" para outro terminal (atualizado), deve-se pressionar Enter no terminal, onde ele deseja recuperar o histórico.
-
opção 1:
shopt -s histappend HISTCONTROL=ignoredups PROMPT_COMMAND="history -a; history -n; $PROMPT_COMMAND"
Isso tem duas desvantagens:
- No login (abrindo um terminal), o último comando do arquivo de histórico é lido duas vezes no buffer de histórico do terminal atual;
- Os buffers de terminais diferentes não ficam sincronizados com o arquivo de histórico.
-
opção 2:
HISTCONTROL=ignoredups PROMPT_COMMAND="history -a; history -c; history -r; $PROMPT_COMMAND"
(Sim, não há necessidade de
shopt -s histappend
e sim, tem que serhistory -c
no meio dePROMPT_COMMAND
) Esta versão também tem dois inconvenientes importantes:- O arquivo de histórico deve ser inicializado. Tem que conter pelo menos uma linha não vazia (pode ser qualquer coisa).
- O comando
history
pode gerar saída falsa - veja abaixo.
[Editar] "E o vencedor é ..."
-
opção 3:
HISTCONTROL=ignoredups:erasedups shopt -s histappend PROMPT_COMMAND="history -n; history -w; history -c; history -r; $PROMPT_COMMAND"
Isso é o máximo possível. É a opção somente para ter o
erasedups
e o histórico comum trabalhando simultaneamente. Esta é provavelmente a solução final para todos os seus problemas, Aahan.
2. Por que a opção 2 parece não funcionar (ou: o que realmente não funciona como esperado)?
Como mencionei, cada uma das soluções acima funciona de maneira diferente. Mas a interpretação mais equivocada de como as configurações funcionam vem da análise da saída de history
command . Em muitos casos, o comando pode fornecer uma saída falsa . Por quê? Porque é executado antes da sequência de outros comandos history
contidos no PROMPT_COMMAND
! No entanto, ao usar a segunda ou terceira opção, pode-se monitorar as mudanças de .bash_history
contents (usando watch -n1 "tail -n20 .bash_history"
por exemplo) e veja qual é a história real.
3. Por que a opção 3 é tão complicada?
Tudo está no modo erasedups
funciona. Como afirma o manual bash, "(...) erasedups
faz com que todas as linhas anteriores que correspondem à linha atual sejam removidas da lista de histórico antes que a linha seja salva" . Então, isso é realmente o que o OP queria (e não apenas, como eu pensava anteriormente, não ter duplicatas aparecendo em seqüência ) . Veja por que cada um dos comandos history -.
tem ou não pode estar no PROMPT_COMMAND
:
-
history -n
tem para estar lá antes dehistory -w
ler.bash_history
dos comandos salvos de qualquer outro terminal, -
history -w
tem para estar lá, a fim de salvar o histórico para arquivar e apagar duplicatas, -
history -a
não deve ser colocado lá em vez dehistory -w
, porque ele não aciona o apagamento de duplicatas, -
history -c
também é necessário porque evita a lixeira do buffer de histórico após cada comando, -
e, finalmente,
history -r
é necessário para restaurar o buffer de histórico do arquivo, finalmente tornando o histórico compartilhado entre sessões de terminal.