Como obter histórico bashed compartilhado entre diferentes guias

19

Eu usei a resposta no link para ativar o histórico compartilhado em tempo real entre os terminais bash separados. Conforme explicado na resposta acima, isso é conseguido adicionando:

# avoid duplicates..
export HISTCONTROL=ignoredups:erasedups  
# append history entries..
shopt -s histappend

# After each command, save and reload history
export PROMPT_COMMAND="history -a; history -c; history -r; $PROMPT_COMMAND"

Isso funciona bem se os shells bash forem separados (por exemplo, abrir diferentes terminais bash usando CTRL+ALT+T . No entanto, não funciona se eu usar tabs (de um terminal aberto 'CTRL + SHIFT + T) em vez de novos Por que essa diferença de comportamento? Como posso compartilhar o histórico bash também entre várias abas?

UPDATE: Eu notei um comportamento incomum: se eu digitar CTRL+C , o último comando digitado em qualquer um dos outros terminais (uma guia ou não) será exibido corretamente. É como se o CTRL + C forças um flush do histórico para que, em seguida, ele seja compartilhado corretamente.

Como exemplo, as saídas (T1 denota o terminal 1 e o terminal 2 T2):

T1:
ls -lah <enter>
# the list of files and directory is shown

T2:
cd Documents <enter>

T1:
<up> (i.e. I press the up arrow)
ls -lah #i.e the last command in terminal 1 is shown rather than the last of terminal 2
^C (i.e. I press CTRL+C)
<up>
cd Documents #the last command issued in terminal 2 is correctly displayed

Espero que isso possa oferecer alguma sugestão!

    
por lucacerone 23.06.2013 / 20:25

4 respostas

2

Parece que você está tentando acessar o histórico do outro terminal antes da sincronização. PROMPT_COMMAND é executado imediatamente antes de um novo prompt ser impresso, ou seja, após você executa um comando e antes de digitar o próximo comando. Portanto, isso não acontecerá imediatamente em T1; você precisa fazer com que um novo prompt seja exibido.

Para testar isso, tente essa variante em suas etapas (adicionei um <enter> extra em T1):

T1:
ls -lah <enter>
# the list of files and directory is shown

T2:
cd Documents <enter>

T1:
<enter>
<up> (i.e. I press the up arrow)

Com essa pressão extra de entrada, você recebe um novo prompt, que executa PROMPT_COMMAND e sincroniza seu histórico, e, portanto, esperaria que essa seta para cima recuperasse o cd em vez do ls , como você queria . Infelizmente, não acho que haja uma maneira de fazer a sincronização acontecer instantaneamente em todos os terminais sem executar nenhum comando como você deseja; efetivamente isso exigiria que todas as suas sessões de login estivessem sincronizando suas listas de histórico continuamente o tempo todo, o que seria um enorme desperdício de CPU e taxa de transferência de disco.

    
por Paul 28.06.2013 / 22:08
1

Eu fiz a mesma pergunta e aqui está a resposta que eu tirei ....

HISTSIZE=9000
HISTFILESIZE=$HISTSIZE
HISTCONTROL=ignorespace:ignoredups

history() {
  _bash_history_sync
  builtin history "[email protected]"
}

_bash_history_sync() {
  builtin history -a         #1
  HISTFILESIZE=$HISTSIZE     #2
  builtin history -c         #3
  builtin history -r         #4
}

PROMPT_COMMAND=_bash_history_sync
    
por Scott Goodgame 26.06.2013 / 12:38
1

adicione as linhas ao seu arquivo .bashrc

# avoid duplicates..
export HISTCONTROL=ignoredups:erasedups  
# append history entries..
shopt -s histappend

trap 'history -r' USR1 
export PROMPT_COMMAND="history -a ; history -c; ps a | awk '/ bash$/ {system (\"kill -USR1 \" \)}'; $PROMPT_COMMAND"

nota:

Inicialmente eu fiz meu bay de teste enviando sinal USR1 para bater com killall, depois pensei em usar um nome de shell uniquee, uma cópia bash chamada testshell, para evitar matar meus próprios shells que poderiam rodar (cron processos por exemplo) mas estranhamente isso não estava funcionando.

O killall não foi seletivo o suficiente, eu substituí-lo por um script que mata apenas os processos bash apertados para um tty ( ps a reporta apenas processos ligados a um tty)

Não se esqueça de reiniciar sua sessão para ter um novo PROMPT_COMMAND. Quando eu estava testando, vi muitos dos meus testes anteriores empilhados dentro de PROMPT_COMMAND.

    
por Emmanuel 01.07.2013 / 19:46
0

Eu tive o mesmo comportamento estranho em Yakuake quando tentei criar um prompt bash elaborado que mostraria o número de outros logins. Número não aumentou para guias. Minha solução foi dizer ao Yakuake executar bash novamente em cada nova aba, essencialmente iniciando o bash no bash. Começou a funcionar perfeitamente. Pode ser que ajudaria você também. Meu palpite é que a GUI para o console carrega as próprias configurações do bash e, em seguida, as alimenta para bash instances. Pode ser que seja capaz de mexer com eles.

    
por Barafu Albino 26.06.2013 / 12:41