GNU/Linux >> Linux Esercitazione >  >> Linux

Aggiorna la cronologia di Bash su altri terminali quando esci da un terminale?

So che questa domanda non è oscura, poiché viene posta qui continua ad aggiornare (e duplicata qui).

Quello che sto cercando di ottenere è un po' diverso. Non mi piace l'idea che il mio prompt riscriva un file ogni ls Digito (history -a; history -c; history -r ).

Vorrei aggiornare il file all'uscita. È facile (in realtà, predefinito), ma devi aggiungere invece di riscrivere:

shopt -s histappend

Ora, quando un terminale è chiuso, vorrei che tutti gli altri che rimangono aperti siano a conoscenza dell'aggiornamento.

Preferisco farlo senza controllare tramite $PS1 su ogni command che scrivo. Penso che sarebbe meglio catturare una sorta di segnale. Come lo faresti? Se non è possibile, magari un semplice cronjob ?

Come possiamo risolvere questo enigma?

Risposta accettata:

Segnali creativi e coinvolgenti, dici? OK:

trap on_exit EXIT
trap on_usr1 USR1

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

on_usr1() {
    history -n
}

Mandalo in .bashrc e vai. Questo utilizza i segnali per dire ogni bash processo per verificare la presenza di nuove voci della cronologia quando ne esce un altro. Questo è piuttosto orribile, ma funziona davvero.

Come funziona?

trap imposta un gestore di segnale per un segnale di sistema o uno degli eventi interni di Bash. Il EXIT event è una terminazione controllata della shell, mentre USR1 è SIGUSR1 , un segnale senza senso che ci stiamo appropriando.

Ogni volta che la shell esce, noi:

  • Aggiungi tutta la cronologia al file in modo esplicito.
  • Disabilita il SIGUSR1 handler e fai in modo che questa shell ignori il segnale.
  • Invia il segnale a tutti coloro che eseguono bash processi dallo stesso utente.

Quando un SIGUSR1 arriva, noi:

  • Carica tutte le nuove voci dal file della cronologia nell'elenco della cronologia in memoria della shell.

A causa del modo in cui Bash gestisce i segnali, non otterrai effettivamente i nuovi dati della cronologia finché non premi Invio la prossima volta, quindi questo non funziona meglio su quel fronte che inserire history -n in PROMPT_COMMAND . Tuttavia, salva la lettura del file costantemente quando non è successo nulla e non viene eseguita alcuna scrittura fino all'uscita della shell.

Ci sono ancora un paio di problemi qui, tuttavia. Il primo è che la risposta predefinita a SIGUSR1 è terminare la shell. Qualsiasi altro bash i processi (esecuzione di script di shell, per esempio) verranno uccisi. .bashrc non viene caricato da shell non interattive. Invece, un file denominato da BASH_ENV è caricato:puoi impostare quella variabile nel tuo ambiente a livello globale in modo che punti a un file con:

trap '' USR1

in esso per ignorare il segnale in essi (che risolve il problema).

Correlati:comando Terminale per scoprire se un server è virtuale o fisico?

Infine, anche se questo fa quello che hai chiesto, l'ordine che riceverai sarà un po' insolito. In particolare, i frammenti di cronologia verranno ripetuti in ordini diversi man mano che vengono caricati e salvati separatamente. Questo è essenzialmente inerente a ciò che stai chiedendo, ma tieni presente che la cronologia della freccia verso l'alto diventa molto meno utile a questo punto. Tuttavia, le sostituzioni della cronologia e simili saranno condivise e funzioneranno bene.


Linux
  1. Conserva la cronologia di Bash in più finestre di terminali?

  2. Perché il prompt di Bash viene disturbato quando sfoglio la cronologia??

  3. Il Bash '?

  4. Rimuovi una determinata riga dal file della cronologia di Bash

  5. Esecuzione di operazioni di scrittura atomica in un file in bash

Comando della cronologia in Linux (Cronologia di Bash)

Bash:aggiungi al file

Come eseguire il backup e il ripristino della cronologia del terminale Linux

35 Esempi di script Bash

Come evitare voci duplicate nella cronologia di Bash in Linux

Cercapersone terminali