
¿Existe algún comando o forma de eliminar todas las entradas del historial de bash Shell que contienen una cadena en particular? Esto será útil para eliminar comandos del historial que contengan contraseña. Sé que podemos eliminar cada entrada del historial por su número, pero el problema es que solo elimina una entrada a la vez y necesito sacar el número cada vez para eliminar una nueva entrada.
p.ej. El comando de historial muestra 5 entradas que contienen la contraseña abcabc y quiero eliminar todas las entradas del comando de historial que contienen la cadena abcabc
975 2019-03-15 11:20:30 ll
976 2019-03-15 11:20:33 ll cd
977 2019-03-15 11:20:36 ll CD
978 2019-03-15 11:20:45 chown test1:test1 CD
979 2019-03-15 11:20:53 chown test1:test1 ./CD
980 2019-03-15 11:20:57 chown test1:test1 .\CD
981 2019-03-15 11:22:04 cd /tmp/logs/
982 2019-06-07 10:36:33 su test1
983 2019-08-22 08:35:10 su user1
984 2019-08-22 08:35:15 /opt/abc/legacy.exe -password abcabc
985 2019-09-24 07:20:45 cd /opt/test1/v6r2017x
986 2019-09-24 07:20:46 ll
987 2019-09-24 07:21:18 cd /tmp/
988 2019-09-24 07:21:19 ll
989 2019-09-24 07:21:24 cd linux_a64/
990 2019-09-24 07:21:25 /opt/abc/legacy.exe -password abcabc
991 2019-09-24 07:24:03 cd build/
992 2019-09-24 07:24:04 ll
993 2019-09-24 07:24:07 cd ..
994 2019-09-24 07:24:10 /opt/abc/legacy.exe -password abcabc
995 2019-09-24 07:24:15 cd someapp/bin
996 2019-09-24 07:24:21 ll
997 2019-09-24 07:24:33 cd .
998 2019-09-24 07:24:35 cd ..
999 2019-09-24 07:24:36 ll
Intenté seguir el comando que dio el error que se indica a continuación
servername:~ # sed -i 'g/abcabc/d' /home/user1/.bash_history
sed: -e expression #1, char 2: extra characters after command
Expectativa: No hay errores y se deben eliminar todas las entradas que contengan la cadena abcabc.
Respuesta1
Otro similar a la respuesta de @cprn pero usando awk
(en lugar de cut
) y una función:
function del_word_history () {
if [ -z "${1}" ]; then return false; fi
mapfile -t result <<< "$(history | grep "${1}" | tac | awk '{print $1}')"
for idx in "${result[@]}"; do
history -d $idx
done
}
tac
invierte las líneas de salida (algunas publicaciones señalaron que no es común a todos los sistemas)[-z $1 ]
:true
si el primer argumento pasado a la función ($1
) está vacío.mapfile -t
(página de manual;algunas guías): leestdin
en una variable de matriz (result
)"${result[@]}"
devuelve la matriz
awk '{print $1}'
(guía de usuarios de GNU,guías breves,página de manual): se utiliza para ambos: identificar una coincidencia y procesarla. Divide los datos delimitados por espacios en blanco (predeterminado) y los almacena en las$n
variables.'{pring $1}'
lee pararealizarprint
acción en la primera palabra.
Uso:
del_word_history history
del_word_history abcabc
history -w
Lo siguiente es unsolución más limpiaque comprueba si obtuvimos el idx
número de history
, en lugar de alguna otra palabra de una entrada de varias líneas:
function del_word_history () {
if [ -z "${1}" ]; then return false; fi
mapfile -t lines <<< "$(history | grep "${1}" | tac)"
for line in "${lines[@]}"; do
idx="$(printf '%s' "${line}" | awk '{ if ($1 ~ /^[0-9]+$/) { print $1 } }')"
if [ -n "${idx}" ]; then
echo "removing line ${idx}"
history -d $idx
fi
done
}
Las principales diferencias son:
- obtenemos las líneas completas en la variable de matriz
lines
a través demapfile
awk '{ if ($1 ~ /^[0-9]+$/) { print $1 }}'
comprueba que la primera palabra de cada línea es un número, y esstdout
esa misma primera palabra (y llega a laidx
variable)[ -n ${idx}" ] just checks if
idx` no está vacío
Respuesta2
Sé que es antiguo pero lo hice en un bucle así:
for ln in $( history | grep my_phrase | cut -f2 -d' '); do
history -d $ln
done
$(...)
- sustitución de comandos, devolucionesstdout
de...
cut -f2 -d' '
- corta la segunda columna de la salida delimitada por espacios, es decir, el número de líneahistory -d $ln
- elimina el número de línea dado del historial
Una línea para copiar y pegar fácilmente:
for ln in $( history | grep my_phrase | cut -f2 -d' '); do history -d $ln; done
Respuesta3
podrías utilizar sed
para eliminar entradas de .bash_history
.
Pero como es una contraseña para evitar escribirla nuevamente en la CLI, le recomendaría que edite su .bashrc
archivo y se asegure de que la línea with HISTCONTROL
esté configurada en ignoreboth
o ignorespace
. Esto le permitiría escribir un comando bash
y no ponerlos en el historial si comienzan con un espacio:
promtpt:$ sed -i '/abcabc/d' /home/user/.bash_history
Observe el espacio entre $
el comando y esto haría que la línea se ignore en el historial de bash.
-i
: significa editar el archivo en línea.
d
al final significa eliminar la línea que contiene la expresión entre /
.
Esta solución sólo funciona en Linux GNU sed
.