Eliminar una determinada línea del archivo de historial de Bash

Respuestas:

109

Debe cerrar sesión y volver a iniciarla o ejecutarla history -apara que el historial actual se confirme en el disco.

Luego solo edite el archivo ~/.bash_history.

Ciro
fuente
19
Si se establece la variable de entorno HISTFILE, el archivo de historial no es ~ / .bash_history sino más bien $ {HISTFILE}.
Karolos
20
Las entradas se escriben en el archivo de historial cuando sale del shell. Por lo tanto, después de ingresar un comando que desea eliminar, debe cerrar la sesión y volver a iniciarla, o usar 'history -d xxxx' para eliminarlos de la sesión de shell actual.
Harmic
3
pero, ¿cómo eliminarías el registro de edición del archivo de historial?
chiliNUT
55
@ chiliNUT: Simplemente comience su comando (por ejemplo vim ~/.bash_history) con un espacio; los comandos que comienzan con un espacio generalmente no se registran (ver $HISTCONTROL).
cYrus
No creo que ese sea el caso en mi distribución, pero en general eso tiene sentido
chiliNUT
149

Puede lograr la eliminación del archivo de historial utilizando la línea de comandos en dos pasos:

  1. Al escribir, se history -d <line_number>elimina una línea específica del historial en la memoria.
  2. Escribir history -wescribe el historial actual en memoria en el ~/.bash_historyarchivo.

Los dos pasos juntos eliminan la línea de forma permanente del historial en memoria y también del archivo .bash_history .

Lampara de papel
fuente
77
¿Cómo borrar el último history -wdel historial?
KrIsHnA
@KrIsHnA edit ~ / .bash_history manualmente
Alexander Myshov
55
O agregue un espacio antes para evitar que se agregue, como en la respuesta de @ tao
Mark
Para encontrar <line_number>solo history | grep [unwanted_content]para obtener una lista con todas las líneas que contienen [unwanted_content](como contraseñas).
AvL
¿Cómo se eliminan varias líneas (específicas) (por id)?
Pathros
39

Para evitar que se agregue un comando al historial en primer lugar, asegúrese de que la variable de entorno HISTCONTROLcontenga entre sus valores separados por dos puntos el valor ignorespace, por ejemplo (agregue, por ejemplo, a .bashrc):

$ export HISTCONTROL=ignorespace

Esto evitará que cualquier comando con un espacio inicial se agregue al historial. Luego puede borrar el historial por completo ejecutando

$  history -c -w
  ^-- additional space character
tao
fuente
32

En primer lugar, si el comando que está a punto de emitir es sensible, inseguro o simplemente no lo necesita abarrotando su historial, lo mejor / más rápido es evitar que ingrese al historial en primer lugar. Asegúrese de que $HISTCONTROLcontiene ignorespace:

(bash)$ echo $HISTCONTROL
ignoredups:ignorespace

Luego proceda cualquier comando que no desee en su historial con un espacio:

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

Si accidentalmente coloca un comando no deseado en el historial, siempre que su sesión de bash todavía esté abierta, el comando aún no ha tocado el disco. Para eliminar el comando anterior en el historial, emita:

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

Tenga en cuenta el espacio inicial; este comando requiere ignorespace, de lo contrario, se eliminará solo.

Si desea eliminar los últimos comandos, busque el último y el primer número del historial:

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

En este caso 602 y 599. Luego emita:

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

(Sin ignorespace, sería 603..599.)

Si no desea que ningún historial de su sesión actual llegue al disco, salga usando:

(bash)$ kill -9 $$

El enfoque hasta ahora es ni siquiera dejar que se escriban elementos del historial confidenciales en el disco para mayor seguridad, porque en teoría los datos eliminados de medios no volátiles aún se pueden recuperar.

Sin embargo, si los comandos que desea eliminar pertenecen a una sesión anterior, ya se habrán agregado a la $HISTFILEsalida. La manipulación de la historia con los comandos anteriores será todavía sólo añadir los restantes nuevos artículos a la $HISTFILE, en la salida . Para sobrescribir el $HISTFILEcon la opinión de la sesión actual de la totalidad de la historia, en este momento , ejecuta:

(bash)$  history -w

Por supuesto, para los elementos del historial que ya están en el disco, la alternativa a editar el historial con history -dcomandos y luego emitirlos history -wes editarlo $HISTFILEcon un editor de texto.

James Haigh
fuente
1
“La manipulación de la historia con los comandos anteriores será todavía sólo anexar los restantes nuevos artículos a la $HISTFILE, en la salida .” En realidad, esto no es exactamente cierto. Parece que solo se añaden los elementos nuevos restantes que 'sobresalen' de la longitud del historial original. Por ejemplo, si elimino 5 elementos originales y agrego 15 nuevos, solo se agregarán los últimos 10 nuevos, mientras que esperaría que se agreguen los 15 nuevos. Creo que esto es un error porque no puedo ver cómo esta funcionalidad es deseable.
James Haigh
1
Supongo que bash toma nota de la longitud original. Al cerrar la sesión, presumiblemente agrega elementos cuyo número es mayor que este valor. Si este valor se disminuye cada vez que se elimina un elemento cuyo número es menor o igual a este valor, funcionaría como se esperaba. ;-)
James Haigh
15

Varias técnicas:

Evitar que la información confidencial se almacene en el archivo de historial

Si ha ingresado alguna contraseña en una línea de comando, entonces tenga en cuenta que todos los comandos están registrados, podría:

  1. Forzar la salida de la sesión actual sin guardar el historial:

     kill -9 $$

    Esto eliminará todo el historial actual.

  2. Escriba ↑ (up arrow)la sesión de bash abierta hasta que se muestre la información confidencial, luego use las teclas de edición de línea como Ctrl+ Wpara eliminar la información confidencial, y luego ↓ (down arrow) hasta que aparezca una nueva línea vacía, antes de escribir Enter.

Eliminar información confidencial del archivo de historial

Si se da cuenta de que la información confidencial ya está almacenada y desea eliminarla, pero no todo su historial:

Un sedcomando simple podría hacer el trabajo:

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

pero, a medida que escribe esto, crea otra línea de historial que contiene el patrón de búsqueda (información confidencial) que está intentando eliminar. Entonces podrías:

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

Esto se ejecutará head -n1con la entrada del terminal. Aparecerá que su terminal está colgada (no habrá un aviso); simplemente escriba la información que desea eliminar del archivo. Este es un truco que le permite ingresar (parte de) un comando sin escribirlo realmente en la línea de comando, por lo que no es elegible para su inclusión en el registro del historial. Luego sedusará el texto que escribió para buscar .bash_history y eliminar todas las líneas que contienen la información confidencial. Nota: si su patrón de información confidencial contiene barras inclinadas, debe escapar de ellas con barras diagonales invertidas, o bien, cambie el sedcomando para usar esta sintaxis para especificar un delimitador que no aparece en el patrón:

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

Otra forma podría ser eliminar solo la información confidencial, pero mantener los comandos que contienen la información. Para esto, simplemente puede reemplazar la información confidencial con el texto sustituto de su elección:

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

Eliminar información confidencial de cualquier archivo en un árbol específico

Finalmente, para asegurarse de que esto no se quede en otro archivo olvidado:

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

enumerará todos los archivos en cuestión.

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

reemplazará todas las apariciones de información confidencial en todos los archivos en el árbol de directorios arraigado en .. Nota: aunque este comando use xargs -0, no manejará archivos con nuevas líneas en sus nombres.

F. Hauri
fuente
11

Busque la línea que desea eliminar presionando ↑ (up arrow)hasta que aparezca, luego presione Ctrl+ U. Eso debería eliminar la línea.

Si usa el historycomando, puede ver que la línea ha sido sustituida por un asterisco.

vicentecarro
fuente
2
En realidad, creo que debe desplazar el cursor hacia arriba hasta la línea, presionar Ctrl + U y luego desplazar el cursor hacia arriba o hacia abajo a otra línea (posiblemente la que está en blanco al final de la lista). Además, estrictamente hablando, la línea no ha sido sustituida por un asterisco. Más bien, el comando se ha borrado y el número del historial se ha agregado con un *.
G-Man
1
Esto se vuelve mucho más poderoso con Ctrl + R (búsqueda de historial incremental inversa), luego, por ejemplo, [Fin], Ctrl + U
sehe
4

Si necesita eliminar varias líneas al mismo tiempo, normalmente uso esto:

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

Si necesita eliminar el último comando, puede usar:

history -d $((HISTCMD-2))
Enlace
fuente
2
Parecía que funcionaba, pero history | grep <string>aún muestra todas las líneas que afirmó eliminar ...
Brock Hensley
1
¡Esto eliminará las líneas incorrectas del historial después de eliminar el fisrt!
mivk
1
Pero afortunadamente, solo imprime los comandos de eliminación incorrectos. Lo siguiente imprimiría los comandos de eliminación correctos:history | grep XYZ | grep -v grep | tac | awk '{print "history -d", $1}'
mivk
3

Si necesita eliminar un rango de líneas del historial, la siguiente función bash podría ahorrarle algo de tiempo:

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 función se debe agregar típicamente a $HOME/.bashrc. Para usar la función inmediatamente, necesitará que el shell se vuelva a leer el archivo ( . $HOME/.bashrc). Luego, para eliminar, por ejemplo, los comandos 200-210 del historial:

$ histdel 200 210

(Nota: esta pregunta se encuentra entre los mejores resultados de búsqueda si busca eliminar un rango de comandos del historial de bash. Por lo tanto, si bien lo anterior es más de lo que la pregunta pregunta, podría ser útil para algunos lectores).

m000
fuente
3
Formas alternativas para la fordeclaración: for n in $(seq "$2" "$1")algunos prefieren estilísticamente y, si seqno funciona, intente for ((n="$2"; n>="$1"; n--)).
Scott
3
history | sed -i 59d

59 es el número de línea. No puede ser nada más dulce que esto :)

KroKite
fuente
3

Solo prueba estos,

$ history

esto mostrará la identificación del historial y el comando, por ej.

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

utilizar,

$ history -d 211

Aquí 211 es el id de la historia. Ahora verifique esto usando

$ history

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

usuario3378188
fuente
2

Sé que ha pasado mucho tiempo desde que se hizo y respondió esta pregunta, pero le mostraré mi método para limpiar mi archivo de historial y cerrar sesión al mismo tiempo.

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

Lo que hace es simple:

  1. history -w : escribe la historia en caché dentro "${HISTFILE}"
  2. nano "${HISTFILE}": permítame editar "${HISTFILE}"Puede usar un script sed o lo que quiera para limpiar su"${HISTFILE}"
  3. history -c : borra el historial en caché para que este último comando no se agregue.
  4. exit : cerrar sesión agregando historial en caché ... pero está vacío;)

Después de ese comando, se cerrará la sesión con un archivo de historial limpio. Inicie sesión para verificar su historial;)

Espero que esto ayude a alguien.

ncenerar
fuente
1

También puede editar el archivo de historial directamente, por ejemplo, nano .bash_historysi está en el shell bash?

Cariño
fuente