Os arquivos de histórico podem ser unificados no bash?

35

Eu costumo executar várias screensessões nos meus desktops e servidores Linux.

Um problema disso é que, grepdurante o meu histórico de comandos, descobri que emiti um comando em uma sessão diferente e preciso desanexar e reconectar para obter esse item do histórico.

É possível 'forçar' as histórias atualizadas de maneira diferente de várias sessões para todas, para uma história central?

Warren
fonte
Corri para um problema semelhante pelo qual não conseguia visualizar o histórico entre as sessões do terminal. Acontece que meu arquivo ~ / .bash_history era de propriedade do root e não era gravável. Alterar proprietário / grupo para o meu usuário corrigiu o problema: sudo chown <user>: <grupo> ~ / .bash_history
mateo

Respostas:

41

Há duas coisas que você precisa fazer:

  1. Insira o comando shopt -s histappendno seu .bashrc. Isso será anexado ao arquivo de histórico em vez de substituí-lo.
  2. Também no seu .bashrc, insira PROMPT_COMMAND="$PROMPT_COMMAND;history -a; history -n"e o arquivo de histórico será reescrito e relido sempre que o bash mostrar o prompt.

EDIT: Graças a e-t172 para o history -ntruque

innaM
fonte
6
Obrigado por isso. Eu melhorei ainda mais usando PROMPT_COMMAND = "$ PROMPT_COMMAND; history -a; history -n". Dessa forma, os comandos emitidos em outras sessões aparecem imediatamente no histórico da sessão atual (bem, você precisa pressionar Enter primeiro para atualizar o histórico).
Etienne Dechamps
8
Eu não tinha PROMPT_COMMANDdefinido anteriormente, então tive que usar PROMPT_COMMAND="history -a; history -n"para evitar erros.
William Jackson
1
consulte a resposta superuser.com/a/734410/250287 para obter os comandos corretos history -a, -c e -r.
mtd
Apenas um alerta para o recém-chegado: depois de usar a reescrita do histórico por um tempo, percebi que estava frequentemente emitindo os comandos errados; quando você vê na linha anterior algum comando, espera que a seta para cima o repita, e com essa configuração não é mais sempre o caso.
Tiago
11

Por favor, não use history -a; history -n, ele não funciona como o esperado e o deixará com muitos comandos duplicados e fora de ordem em seu histórico. Uma solução que funciona geralmente conforme o esperado é a seguinte:

# unified bash history
shopt -s histappend
PROMPT_COMMAND="${PROMPT_COMMAND:+$PROMPT_COMMAND$'\n'}history -a; history -c; history -r"

Usar uma nova linha em vez de um ponto e vírgula também é uma maneira curta de lidar com o problema de ponto e vírgula ausente / duplicado com o PROMPT_COMMAND.

Adam Crane
fonte
história -a, -c, e depois -r está correto ... esta deve ser a resposta aceita
mtd
1
O exportnão é necessário. Como as opções interativas do shell devem ser definidas a partir das ~/.bashrcquais é chamada a partir de cada sub shell, a herança não é necessária.
dolmen
Existe uma boa razão para não usar apenas PROMPT_COMMAND="history -a; history -c; history -r; $PROMPT_COMMAND"?
6
Essa ordem exigiria que você armazenasse o último valor de saída antes de executar os comandos do histórico, uma vez que muitos comandos de prompt dependem ou os exibem.
Adam guindaste
-1

PROMPT_COMMAND não está definido por padrão em algumas distros. Por exemplo, é definido no Arch, mas não no Debian.

Tenho um bashrc no meu Dropbox que uso durante a distribuição de distros e inclui:

PROMPT_COMMAND="$( [ '$PROMPT_COMMAND' ] && echo $PROMPT_COMMAND; )history -a; history -n"
czayas
fonte
Uma solução terrível para um problema básico de programação de shell. O caminho certo:PROMPT_COMMAND="$PROMPT_COMMAND; history -a; history -n"
dolmen
Melhor:PROMPT_COMMAND="$PROMPT_COMMAND"$'\n''history -a; history -n'
dolmen