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.