GNU/Linux >> Linux Esercitazione >  >> Linux

Storia di Bash:"ignoredups" e "erasedups" che creano conflitto con la storia comune nelle sessioni?

Prima di tutto, questo non è un duplicato di alcun thread esistente su SE. Ho letto questi due thread (1°, 2°) su una migliore cronologia di bash, ma nessuna delle risposte funziona – – A proposito, sono su Fedora 15.

Ho aggiunto quanto segue a .bashrc file nella directory utente (/home/aahan/) e non funziona. Qualcuno ha un indizio?

HISTCONTROL=ignoredups:erasedups  # no duplicate entries
HISTSIZE=1000                     # custom history size
HISTFILESIZE=100000                 # custom history file size
shopt -s histappend                      # append to history, don't overwrite it
PROMPT_COMMAND="history -a; history -c; history -r; $PROMPT_COMMAND"  # Save and reload the history after each command finishes

Va bene, questo è quello che voglio con la cronologia di bash (priorità):

  • non archiviare duplicati, cancella quelli esistenti
  • Condividi immediatamente la cronologia con tutti i terminali aperti
  • aggiungi sempre la cronologia, non sovrascriverla
  • Memorizza i comandi su più righe come un unico comando (che è disattivato per impostazione predefinita)
  • qual è la dimensione predefinita della cronologia e la dimensione del file della cronologia?

Risposta accettata:

Questo è in realtà un comportamento davvero interessante e confesso di aver sottovalutato molto la domanda all'inizio. Ma prima i fatti:

1. Cosa funziona

La funzionalità può essere raggiunta in diversi modi, sebbene ognuno funzioni in modo leggermente diverso. Si noti che, in ogni caso, per avere lo storico “trasferito” su un altro terminale (aggiornato), è necessario premere Invio nel terminale, dove vuole recuperare la cronologia.

  • opzione 1:

     shopt -s histappend
     HISTCONTROL=ignoredups
     PROMPT_COMMAND="history -a; history -n; $PROMPT_COMMAND"
    

Questo ha due svantaggi:

  1. Al login (apertura di un terminale), l'ultimo comando dal file di cronologia viene letto due volte nel buffer di cronologia del terminale corrente;
  2. I buffer dei diversi terminali non rimangono sincronizzati con il file della cronologia.
  • opzione 2:

     HISTCONTROL=ignoredups
     PROMPT_COMMAND="history -a; history -c; history -r; $PROMPT_COMMAND"
    

(Sì, non c'è bisogno di shopt -s histappend e sì, deve esserlo history -c nel mezzo di PROMPT_COMMAND )
Questa versione presenta anche due importanti inconvenienti:

  1. Il file della cronologia deve essere inizializzato. Deve contenere almeno una riga non vuota (può essere qualsiasi cosa).
  2. La history il comando può dare un output falso – vedi sotto.

[Modifica] "E il vincitore è..."

  • opzione 3:

     HISTCONTROL=ignoredups:erasedups
     shopt -s histappend
     PROMPT_COMMAND="history -n; history -w; history -c; history -r; $PROMPT_COMMAND"
    

Questo è il massimo. È l'unico opzione per avere entrambi erasedups e la storia comune che lavorano simultaneamente. Questo è probabilmente la soluzione finale a tutti i tuoi problemi, Aahan.

2. Perché l'opzione 2 non sembra funzionare (oppure:cosa realmente non funziona come previsto)?

Come ho già detto, ciascuna delle soluzioni di cui sopra funziona in modo diverso. Ma l'interpretazione più fuorviante del funzionamento delle impostazioni deriva dall'analisi dell'output della history comando . In molti casi, il comando può dare false produzione. Come mai? Perché viene eseguito prima la sequenza di altri history comandi contenuti nel PROMPT_COMMAND ! Tuttavia, quando si utilizza la seconda o la terza opzione, è possibile monitorare le modifiche di .bash_history contenuti (usando watch -n1 "tail -n20 .bash_history" per esempio) e vedere qual è la vera storia.

Correlati:Perché l'uscita di tensione di un generatore di segnali cambia con la sua impostazione di frequenza?

3. Perché opzione 3 è così complicato?

Tutto sta nel modo in cui erasedups lavori. Come afferma il manuale di bash, “(…) erasedups fa sì che tutte le righe precedenti corrispondenti alla riga corrente vengano rimosse dall'elenco della cronologia prima che quella riga venga salvata" . Quindi questo è davvero ciò che l'OP voleva (e non solo, come pensavo in precedenza, che non comparissero duplicati in sequenza ) . Ecco perché ciascuno dei history -. i comandi devono o non possono essere nel PROMPT_COMMAND :

  • history -n ha essere lì prima di history -w per leggere da .bash_history i comandi salvati da qualsiasi altro terminale,

  • history -w ha essere lì per salvare la nuova cronologia nel file dopo che bash ha verificato se il comando era un duplicato,

  • history -a non deve essere posizionato lì al posto di history -w , perché aggiungerà al file qualsiasi nuovo comando, indipendentemente dal fatto che sia stato selezionato come duplicato.

  • history -c è anche necessario perché impedisce di cestinare il buffer della cronologia dopo ogni comando,

  • e infine, history -r è necessario per ripristinare il buffer della cronologia dal file, rendendo così finalmente la cronologia condivisa tra le sessioni del terminale.

Tieni presente che questa soluzione rovinerà l'ordine della cronologia mettendo tutta la cronologia da altri terminali davanti al comando più recente inserito nel terminale corrente. Inoltre, non elimina le righe duplicate già nel file della cronologia a meno che non immetti di nuovo quel comando.


Linux
  1. trova e copia il file usando Bash

  2. Usando la cronologia di bash per ottenere un comando precedente, copialo e poi "eseguilo" ma con il comando commentato

  3. echo testo con nuova riga in bash

  4. Come mantengo la mia cronologia di bash tra le sessioni?

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

Migliora la tua cronologia delle shell con Loki e fzf

Comando zip e decomprimi Linux con esempi

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

Reindirizzamento Bash spiegato con esempi

Come cancellare la cronologia di Bash in Linux e Mac

Cos'è esattamente <() in bash (e =() in zsh)?