Atualiza o histórico de bash em outros terminais ao sair de um terminal

14

Eu sei que essa pergunta não é obscura, como é perguntado aqui continue atualizando (e duplicado aqui).

O que estou tentando alcançar é um pouco diferente. Eu não gosto da idéia do meu prompt de reescrever um arquivo a cada ls tipo ( history -a; history -c; history -r ).

Gostaria de atualizar o arquivo ao sair. Isso é fácil (na verdade, padrão), mas você precisa anexar em vez de reescrever:

shopt -s histappend

Agora, quando um terminal está fechado, gostaria de deixar todos os outros que permanecem abertos para saberem da atualização.

Eu prefiro fazer isso sem verificar via $PS1 em cada command que eu digito. Eu acho que seria melhor capturar algum tipo de sinal. Como você faria isso? Se não for possível, talvez um simples cronjob ?

Como podemos resolver esse quebra-cabeça?

    
por Dr Beco 28.06.2015 / 00:06

1 resposta

14

Sinais criativos e envolventes, você diz? OK:

trap on_exit EXIT
trap on_usr1 USR1

on_exit() {
    history -a
    trap '' USR1
    killall -u "$USER" -USR1 bash
}

on_usr1() {
    history -n
}

Chuck que em .bashrc e vai. Isso usa sinais para dizer a cada processo de bash para verificar novas entradas de histórico quando outra sair. Isso é muito ruim, mas funciona mesmo.

Como funciona?

trap define um manipulador de sinal para um sinal do sistema ou um dos eventos internos do Bash. O evento EXIT é qualquer terminação controlada do shell, enquanto USR1 é SIGUSR1 , um sinal sem sentido que estamos apropriando.

Sempre que o shell sai, nós:

  • Anexar todo o histórico ao arquivo explicitamente.
  • Desative o manipulador SIGUSR1 e torne esse shell ignore o sinal .
  • Envie o sinal para todos os processos em execução bash do mesmo usuário.

Quando um SIGUSR1 chega, nós:

  • Carregue todas as novas entradas do arquivo de histórico na lista de histórico na memória do shell.

Por causa do modo como o Bash manipula os sinais, você não obterá os novos dados do histórico até que você pressione Enter na próxima vez, então isso não será melhor do que colocar < href="https://www.gnu.org/software/bash/manual/bashref.html#index-history"> history -n em PROMPT_COMMAND . Ele salva a leitura do arquivo constantemente quando nada aconteceu, e não há nenhuma escrita até que o shell saia.

Ainda há alguns problemas aqui, no entanto. A primeira é que a resposta padrão para SIGUSR1 é terminar o shell. Quaisquer outros processos bash (executando scripts de shell, por exemplo) serão eliminados. .bashrc não é carregado por shells não interativos. Em vez disso, um arquivo chamado por BASH_ENV é carregado : você pode defina essa variável em seu ambiente globalmente para apontar para um arquivo com:

trap '' USR1

nele para ignorar o sinal neles (que resolve o problema).

Finalmente, embora isso faça o que você pediu, o pedido será um pouco incomum. Em particular, os bits do histórico serão repetidos em diferentes ordens à medida que forem carregados e salvos separadamente. Isso é essencialmente inerente ao que você está pedindo, mas esteja ciente de que a história da seta para cima se torna muito menos útil neste momento. Substituições do histórico e similares serão compartilhadas e funcionarão bem. p>     

por 28.06.2015 / 01:28