Strano comportamento della cronologia bash quando si eseguono più sessioni


15

Come viene memorizzata la cronologia della riga di comando quando utilizzo più finestre del terminale? So che è archiviato .bash_historyma non riesco a vedere la logica su quale cronologia viene utilizzata se apro una nuova finestra. Sembra quasi non deterministico in un certo senso che non so mai quale comando vedrò se provo a usare la freccia su in una nuova finestra.

Qualcuno può spiegare questo?

Esiste un modo per controllare la cronologia in modo tale da poter riutilizzare la cronologia da una determinata finestra?

Risposte:


14

Per capire prima il comportamento della storia di bash devi sapere quanto segue:

  1. C'è la cronologia nel file cronologico.
  2. C'è la storia nella memoria di un processo bash.
  3. La cronologia nella memoria di un processo bash non è sincronizzata con la cronologia nella memoria di nessun altro processo bash.
  4. La cronologia nella memoria di un processo bash non è sincronizzata con la cronologia nel file, a meno che non sia esplicitamente richiesto o durante un evento specifico (vedere di seguito).

Utilizzando le impostazioni predefinite, il ciclo di vita di una sessione bash per quanto riguarda la cronologia è il seguente:

  1. Durante l'avvio bash leggerà il file della cronologia. Il contenuto del file della cronologia è ora nella memoria del processo bash.
  2. Durante l'uso normale viene manipolata solo la cronologia in memoria.
  3. Durante l'arresto la cronologia in memoria viene scritta nel file cronologico, sovrascrivendo qualsiasi contenuto precedente del file cronologico.

Il comportamento apparentemente non deterministico che hai osservato è principalmente perché il contenuto del file di cronologia è sempre la cronologia dell'ultima sessione di bash chiusa e bash legge il file di cronologia solo all'avvio.

Leggi il manuale di bash per una spiegazione più dettagliata del processo di avvio e spegnimento.

Si noti che con le impostazioni predefinite intendo le impostazioni predefinite di bash. La tua distribuzione potrebbe aver fornito un .bashrc(o /etc/bash.bashrc) che modifica questo comportamento.

Abilitando l'opzione shell histappendpuoi dire a bash di aggiungere invece di sovrascrivere il file della cronologia. Puoi abilitare histappendusando il comando shopt -s histappend. Per avere questa opzione sempre abilitata devi inserire il comando nel tuo .bashrc(o altro file di inizializzazione). Maggiori informazioni sul shoptcomando nel manuale di bash

Si noti che l'abilitazione histappendnon ridurrà di molto il comportamento apparentemente non deterministico. Questo perché ogni sessione di bash ha ancora la sua storia in memoria. È possibile avere una cronologia bash per lo più sincronizzata. C'è una guida su come ottenere che ogni processo bash abbia una cronologia per lo più sincronizzata in un thread su overflow dello stack .

usando il comando incorporato historypuoi dire esplicitamente a bash di leggere la cronologia da file a memoria, o di scrivere da memoria a file. Ad esempio: history -rleggerà il contenuto del file e lo aggiungerà alla cronologia in memoria. history -wscriverà la cronologia corrente dalla memoria al file, sovrascrivendo il contenuto precedente. Questo è fondamentalmente ciò che accade durante l'arresto. Maggiori informazioni sul historycomando nel manuale di bash

Per completezza ecco un elenco delle variabili interne che modificano il comportamento della cronologia:

  • HISTFILE: il file da cui leggere e scrivere la cronologia.
  • HISTFILESIZE: il numero massimo di righe per il file cronologico.
  • HISTSIZE: il numero massimo di righe per la cronologia in memoria.
  • HISTCONTROL, HISTIGNORE, HISTTIMEFORMAT: Non rilevante per questa discussione. Leggi il manuale di bash per i dettagli.

Buona spiegazione Hai menzionato l'arresto, ma per quanto riguarda l'uccisione della sessione terminale? La sessione può essere interrotta tramite disconnessione o tramite l'interfaccia utente o tramite altri mezzi come l'interruzione della connessione di rete. Se l'intero file della cronologia viene sostituito e hai più sessioni, stai dicendo che la cronologia dell'ultima chiusa verrà utilizzata nel file della cronologia? Ciò potrebbe spiegare un comportamento non deterministico.
Alex Gitelman,

il punto del ciclo di vita (3) non è corretto. Sembra che solo la prima sessione bash scriverà mai nel file della cronologia. Test: aprire 2 sessioni nell'ordine- a, b. Fai 'ciao eco' in b . Quindi uscire in b . Quindi aprire una nuova sessione c . Questa sessione non avrà l'eco ciao nella sua storia.
user606723

@AlexGitelman: se un processo bash viene interrotto, non avrà la possibilità di sovrascrivere il file cronologico. e sì, la cronologia dell'ultima sessione chiusa è quella che sarà nel file della cronologia.
lesmana,

@ user606723: il punto 3 è corretto. leggi il manuale di bash. riprovare utilizzando un .bashrcfile minimo . nota che la tua distribuzione potrebbe aver modificato alcune impostazioni in /etc/bash.bashrc. controlla specificamente l'opzione shell histappend.
lesmana,


0

AFAIK, i comandi bash vengono salvati al termine della sessione SSH. Pertanto, i comandi non vengono salvati quando una sessione termina in modo anomalo (ad esempio, a causa di un errore di rete). Sto parlando qui delle sessioni SSH. I terminali locali possono utilizzare un approccio simile.

Quando si aprono più sessioni contemporaneamente, i comandi digitati su una sessione non vengono visualizzati sull'altra mentre sono entrambi attivi. Tuttavia, vedrai questi comandi quando finisci la sessione riaprila.


Questo non è il comportamento che ho provato. Posso confermarlo facendo un rapido test in cui apro una sessione ssh, eseguo un comando e faccio un'uscita graziosa. In questo caso, ho avuto un'altra sessione ssh precedentemente attiva. In questa sessione bash preesistente, controllo .bash_history e non trovo nulla di registrato. Trovo probabile che la prima sessione bash in esecuzione sia l'unica che finisce per registrare su .bash_history.
user606723

La chiusura della sessione non influirà sulle sessioni attualmente in esecuzione, ma influenzerà le nuove sessioni!
Khaled,

E se non fosse SSH ma la finestra del terminale di Gnome che chiudo tramite l'interfaccia utente?
Alex Gitelman,

Deve essere verificato. Attualmente, non ho accesso a un terminale Gnome!
Khaled,

@Khaled, testato, non influisce sulle nuove sessioni. (Ho controllato .bash_history prima comunque, che è dove bash ottiene la cronologia dei comandi per le nuove sessioni, sapevo che non avrebbe funzionato, ma ti ho umorizzato comunque.)
user606723
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.