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:
- Al login (apertura di un terminale), l'ultimo comando dal file di cronologia viene letto due volte nel buffer di cronologia del terminale corrente;
- 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:
- Il file della cronologia deve essere inizializzato. Deve contenere almeno una riga non vuota (può essere qualsiasi cosa).
- 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.
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 dihistory -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 dihistory -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.