Rimuovi una determinata riga dal file della cronologia di Bash


Risposte:


109

È necessario disconnettersi e riconnettersi o eseguirlo in history -amodo che la cronologia corrente sia impegnata sul disco.

Quindi modifica il file ~/.bash_history.


19
Se la variabile di ambiente HISTFILE è impostata, il file della cronologia non è ~ / .bash_history ma piuttosto $ {HISTFILE}.
Karolos,

20
Le voci vengono scritte nel file cronologico quando si esce dalla shell. Pertanto, dopo aver immesso un comando che si desidera rimuovere, è necessario disconnettersi e riconnettersi oppure utilizzare 'history -d xxxx' per rimuoverli dalla sessione di shell corrente.
Harmic

3
ma come cancelleresti il ​​record di modifica del file della cronologia?
chiliNUT,

5
@chiliNUT: basta avviare il comando (ad es. vim ~/.bash_history) con uno spazio; i comandi che iniziano con uno spazio di solito non vengono registrati (vedi $HISTCONTROL).
cYrus,

Non penso che sia il caso nella mia distribuzione, ma in generale ha senso
chiliNUT il

149

È possibile ottenere la rimozione dal file della cronologia utilizzando la riga di comando in due passaggi:

  1. La digitazione history -d <line_number>elimina una riga specificata dalla cronologia in memoria.
  2. La digitazione history -wscrive la cronologia corrente in memoria nel ~/.bash_historyfile.

I due passaggi insieme rimuovono definitivamente la linea dalla cronologia in memoria e anche dal file .bash_history .


7
come eliminare l'ultimo history -wdalla cronologia?
KrIsHnA

@KrIsHnA modifica ~ / .bash_history manualmente
Alexander Myshov,

5
Oppure aggiungi uno spazio prima di impedirne l'aggiunta, come nella risposta di @ tao
Segna il

Per trovare <line_number>solo history | grep [unwanted_content]per ottenere un elenco con tutte le righe contenenti [unwanted_content](come le password).
AvL

Come si eliminano più righe (specifiche) (per ID)?
Pathros,

39

Per evitare che un comando venga aggiunto alla cronologia in primo luogo, assicurarsi che la variabile di ambiente HISTCONTROLcontenga tra i suoi valori separati da due punti il ​​valore ignorespace, ad esempio (aggiungi ad esempio a .bashrc):

$ export HISTCONTROL=ignorespace

Ciò impedirà che qualsiasi comando con uno spazio iniziale venga aggiunto alla cronologia. È quindi possibile cancellare completamente la cronologia eseguendo

$  history -c -w
  ^-- additional space character

32

Prima di tutto, se il comando che stai per emettere è sensibile, non sicuro o se non ne hai semplicemente bisogno, ingombrando la tua cronologia, è meglio / più veloce impedire che entri nella cronologia in primo luogo. Assicurarsi che $HISTCONTROLcontenga ignorespace:

(bash)$ echo $HISTCONTROL
ignoredups:ignorespace

Quindi procedi con uno spazio che non vuoi nella tua storia:

(bash)$  sensitive-cmd-with --password 82cf7dfe
(bash)$  rm -r... # One-off recursive remove; mustn't be accidentally repeated!

Se hai inserito accidentalmente un comando indesiderato nella cronologia, a condizione che la tua sessione bash sia ancora aperta, il comando non ha ancora toccato il disco. Per eliminare il comando precedente nella cronologia, emettere:

(bash)$  history -d $((HISTCMD-1))

Nota lo spazio iniziale; questo comando richiede ignorespace, altrimenti si cancellerà da solo!

Se desideri eliminare gli ultimi comandi, trova l'ultimo e il primo numero di cronologia:

(bash)$  history 5
  598  ok
  599  sensitive
  600  unsafe
  601  doesn\'t-work
  602  otherwise-unwanted

In questo caso 602 e 599. Quindi rilasciare:

(bash)$  for i in {602..599}; do history -d $i; done

(Senza ignorespace, sarebbe 603..599.)

Se non si desidera alcuna storia della sessione corrente per colpire il disco, uscire con:

(bash)$ kill -9 $$

L'approccio finora non è nemmeno quello di lasciare che gli elementi della cronologia sensibili vengano scritti su disco per una maggiore sicurezza, poiché in teoria i dati eliminati da supporti non volatili possono ancora essere recuperati.

Se, tuttavia, i comandi che desideri rimuovere provengono da una sessione precedente, saranno già stati aggiunti $HISTFILEall'uscita all'uscita. Manipolare la storia con i comandi di cui sopra sarà ancora solo aggiungerà i restanti nuovi elementi al $HISTFILE, in uscita . Per sovrascrivere il $HISTFILEcon la vista della sessione corrente dell'intera cronologia, in questo momento , problema:

(bash)$  history -w

Naturalmente per gli elementi della cronologia già presenti sul disco, l'alternativa alla modifica della cronologia con i history -dcomandi e poi l'emissione history -wè quella di modificarli $HISTFILEcon un editor di testo.


1
“Manipolare la storia con i comandi di cui sopra sarà ancora solo accodare i restanti nuovi elementi al $HISTFILE, in uscita .” In realtà, questo non è esattamente vero. Sembra solo aggiungere nuovi elementi rimanenti che "sporgono" dalla lunghezza della cronologia originale. Ad esempio, se rimuovo 5 elementi originali e ne aggiungo 15 nuovi, vengono aggiunti solo gli ultimi 10 nuovi, mentre mi aspetto che vengano aggiunti tutti e 15 i nuovi. Penso che questo sia un bug perché non riesco a vedere come questa funzionalità sia mai desiderabile.
James Haigh,

1
Immagino che bash prenda nota della lunghezza originale. Alla chiusura della sessione, presumibilmente aggiunge elementi il ​​cui numero è maggiore di questo valore. Se questo valore fosse decrementato ogni volta che un elemento viene eliminato il cui numero è inferiore o uguale a questo valore, funzionerebbe come previsto. ;-)
James Haigh,

15

Diverse tecniche:

Impedire che informazioni sensibili vengano archiviate nel file cronologico

Se hai inserito una password su una riga di comando, ti rendi conto che tutti i comandi sono registrati, puoi:

  1. Forza l'uscita dalla sessione corrente senza salvare la cronologia:

     kill -9 $$

    Questo lascerà cadere tutta la cronologia attuale.

  2. Digita ↑ (up arrow)la sessione bash aperta fino a quando non vengono visualizzate le informazioni riservate, quindi usa i tasti di modifica delle righe come Ctrl+ Wper eliminare le informazioni sensibili, quindi ↓ (down arrow) fino a quando non viene richiesta una nuova riga vuota, prima di digitare Enter.

Elimina le informazioni sensibili dal file della cronologia

Se ti rendi conto che le informazioni sensibili sono già memorizzate e desideri eliminarle, ma non l'intera cronologia:

Un semplice sedcomando potrebbe fare il lavoro:

sed -e '/SeNsItIvE InFo/d' -i .bash_history

ma, mentre lo digiti, crei un'altra riga della cronologia contenente il modello di ricerca (informazioni sensibili) che stai tentando di eliminare. Quindi potresti:

sed -e "/$(head -n1)/d" -i .bash_history

Questo verrà eseguito head -n1con input dal terminale. Apparirà che il tuo terminale è bloccato (non ci sarà un prompt); digita semplicemente le informazioni che desideri eliminare dal file. Questo è un trucco per farti inserire (parte di) un comando senza digitarlo nella riga di comando, rendendolo quindi non idoneo per l'inclusione nel record della cronologia. Quindi sedutilizzerà il testo digitato per cercare .bash_history ed eliminare tutte le righe contenenti le informazioni sensibili. Nota: se il modello di informazioni sensibili contiene barre (es), è necessario evitarle con barre rovesciate, oppure modificare il sedcomando per utilizzare questa sintassi per specificare un delimitatore che non appare nel modello:

sed -e "\|$(head -n1)|d" -i .bash_history

Un altro modo potrebbe essere quello di eliminare solo le informazioni sensibili, ma mantenere i comandi che contengono le informazioni. Per questo, potresti semplicemente sostituire le informazioni sensibili con un testo sostitutivo a tua scelta:

sed -e "s/$(head -n1)/Santa Claus/g" -i .bash_history.

Elimina le informazioni sensibili da qualsiasi file in un albero specifico

Infine, per essere sicuro che questo non rimarrà in un altro file dimenticato:

SENSITIVEINFO="$(head -n1)"
find . -type f -print0 | xargs -0 grep -l "$SENSITIVEINFO"

elencherà tutti i file interessati.

find . -type f -print0 |
    xargs -0 grep -l "$SENSITIVEINFO" |
    tr \\n \\0 |
    xargs -0 sed -e "s/$SENSITIVEINFO/Santa Claus/g" -i

sostituirà tutte le occorrenze di informazioni sensibili in tutti i file nella struttura di directory su cui è stato effettuato il root .. Nota: anche se questo comando utilizza xargs -0, non gestirà i file con le nuove righe nei loro nomi.


11

Individua la linea che desideri eliminare premendo ↑ (up arrow)fino a quando non viene visualizzata, quindi premi Ctrl+ U. Questo dovrebbe rimuovere la linea.

Se si utilizza il historycomando, è possibile vedere che la riga è stata sostituita con un asterisco.


2
In realtà, credo che devi spostare il cursore verso l'alto fino alla linea, premere Ctrl + U, quindi il cursore verso l'alto o verso il basso su un'altra riga (possibilmente quella vuota in fondo all'elenco). Inoltre, a rigor di termini, la linea non è stata sostituita da un asterisco. Piuttosto, il comando è stato cancellato e il numero di cronologia è stato aggiunto con un *.
G-Man

1
Questo diventa molto più potente con Ctrl + R (ricerca cronologica incrementale inversa), ad esempio [Fine], Ctrl + U
sehe

4

Se è necessario rimuovere più righe contemporaneamente, normalmente utilizzo questo:

history | grep <string> | cut -d ' ' -f 3 | awk '{print "history -d " $1}'

Se devi rimuovere l'ultimo comando puoi usare:

history -d $((HISTCMD-2))

2
Sembrava che funzionasse, ma history | grep <string>mostra ancora tutte le righe che ha affermato di eliminare ...
Brock Hensley,

1
Ciò eliminerà le righe della cronologia errate dopo aver eliminato il primo !!
mivk,

1
Ma per fortuna, stampa solo i comandi di eliminazione errati. Di seguito verrebbero stampati i comandi di eliminazione corretti:history | grep XYZ | grep -v grep | tac | awk '{print "history -d", $1}'
mivk

3

Se devi rimuovere un intervallo di righe dalla cronologia, la seguente funzione bash potrebbe farti risparmiare un po 'di tempo:

function histdel() {
    [ $# -eq 1 ] && history -d "$1" && history -w
    if [ $# -eq 2 -a "$1" -le "$2" ]; then
        for n in `seq "$2" "$1"`; do
            history -d "$n"
        done
        history -w
    fi
}

La funzione dovrebbe in genere essere aggiunta a $HOME/.bashrc. Per utilizzare immediatamente la funzione, è necessario leggere nuovamente il file dalla shell in esecuzione ( . $HOME/.bashrc). Quindi per eliminare ad es. I comandi 200-210 dalla cronologia:

$ histdel 200 210

(Nota: questa domanda è tra i migliori risultati di ricerca se si cerca di eliminare una serie di comandi dalla cronologia di bash. Quindi, mentre quanto sopra è più di quello che la domanda pone, potrebbe essere utile per alcuni lettori.)


3
Moduli alternativi per l' foraffermazione: for n in $(seq "$2" "$1")è stilisticamente preferito da alcuni e, se seqnon funziona, prova for ((n="$2"; n>="$1"; n--)).
Scott,

3
history | sed -i 59d

59 è il numero di riga. Non può essere niente di più dolce di questo :)


3

Prova questi,

$ history

questo visualizzerà l'id della cronologia e il comando, ad es

.
.
211 ls
212 javac Welcome.java
213 java welcome
.
.

uso,

$ history -d 211

Qui 211 è l'id della storia. Ora controlla questo usando

$ history

.
.
211 javac Welcome.java
212 java welcome
.
.


2

So che è passato molto tempo da quando questa domanda è stata posta e ha risposto, ma ti mostrerò il mio metodo per pulire il mio file di cronologia e disconnettermi allo stesso tempo.

Io corro : history -w && nano "${HISTFILE}" && history -c && exit

Quello che fa è semplice:

  1. history -w : scrive la cronologia memorizzata nella cache "${HISTFILE}"
  2. nano "${HISTFILE}": permettimi di modificare "${HISTFILE}"Puoi usare uno script sed o qualunque cosa tu voglia pulire"${HISTFILE}"
  3. history -c : cancella la cronologia memorizzata nella cache in modo che quest'ultimo comando non venga aggiunto.
  4. exit : disconnettimi aggiungendo la cronologia cache ... ma è vuota;)

Dopo quel comando, verrai disconnesso con un file di cronologia pulito. Accedi per controllare la tua cronologia;)

Spero che questo possa aiutare qualcuno.


1

Potresti anche modificare direttamente il file della cronologia, ad esempio nano .bash_historyse sei nella shell bash?

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.