Supprimer une certaine ligne du fichier historique Bash

Réponses:

109

Vous devez vous déconnecter et vous reconnecter ou exécuter history -apour que l'historique actuel soit enregistré sur le disque.

Ensuite, éditez simplement le fichier ~/.bash_history.

cYrus
la source
19
Si la variable d'environnement HISTFILE est définie, le fichier d'historique n'est pas ~ / .bash_history mais plutôt $ {HISTFILE}.
Karolos
20
Les entrées sont écrites dans le fichier historique lorsque vous quittez le shell. Par conséquent, après avoir entré une commande que vous souhaitez supprimer, vous devez vous déconnecter et vous reconnecter, ou utilisez 'history -d xxxx' pour les supprimer de la session shell en cours.
harmic
3
mais comment voulez-vous supprimer l'enregistrement de l'édition du fichier d'historique?
chiliNUT
5
@chiliNUT: Il suffit de lancer votre commande (par exemple vim ~/.bash_history) avec un espace; les commandes commençant par un espace ne sont généralement pas enregistrées (voir $HISTCONTROL).
cYrus
Je ne pense pas que ce soit le cas dans ma distribution, mais en général, cela a du sens
chiliNUT
149

Vous pouvez supprimer le fichier d'historique à l'aide de la ligne de commande en deux étapes:

  1. La frappe history -d <line_number>supprime une ligne spécifiée de l'historique en mémoire.
  2. La saisie history -wécrit l'historique actuel en mémoire dans le ~/.bash_historyfichier.

Les deux étapes combinées suppriment la ligne de façon permanente de l' historique en mémoire et du fichier .bash_history .

Lanterne de papier
la source
7
Comment effacer le dernier history -wde l'historique?
KrIsHnA
@KrIsHnA modifier ~ / .bash_history manuellement
Alexander Myshov
5
Ou ajoutez un espace avant pour l'empêcher d'être ajouté, comme dans la réponse de @ tao
Mark
Pour trouver <line_number>juste history | grep [unwanted_content]pour obtenir une liste avec toutes les lignes contenant [unwanted_content](comme les mots de passe).
AvL
Comment supprimez-vous plusieurs lignes (spécifiques) (par id)?
Pathros
39

Pour éviter qu'une commande ne soit ajoutée à l'historique en premier lieu, assurez-vous que la variable d'environnement HISTCONTROLcontient parmi ses valeurs séparées par des deux-points la valeur ignorespace, par exemple (add eg to .bashrc):

$ export HISTCONTROL=ignorespace

Cela empêchera toute commande avec un espace de début d'être ajoutée à l'historique. Vous pouvez ensuite effacer complètement l'historique en exécutant

$  history -c -w
  ^-- additional space character
tao
la source
32

Tout d'abord, si la commande que vous êtes sur le point d'émettre est sensible, dangereuse ou si vous n'avez pas besoin de l'encombrer dans votre historique, il est préférable de l'empêcher d'entrer dans l'historique en premier lieu. Assurez-vous que cela $HISTCONTROLcontient ignorespace:

(bash)$ echo $HISTCONTROL
ignoredups:ignorespace

Ensuite, effectuez toute commande que vous ne voulez pas dans votre historique avec un espace:

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

Si vous avez accidentellement ajouté une commande indésirable à l'historique, à condition que votre session bash soit toujours ouverte, la commande n'a pas encore touché le disque. Pour supprimer la commande précédente de l'historique, tapez:

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

Notez l'espace de premier plan; cette commande nécessite ignorespace, sinon elle va juste se supprimer!

Si vous souhaitez supprimer les dernières commandes, recherchez le dernier et le premier numéro d'historique:

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

Dans ce cas, 602 et 599. Ensuite, publiez:

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

(Sans ignorespace, ce serait 603..599.)

Si vous ne souhaitez pas que l' historique de votre session actuelle accède au disque, quittez en utilisant:

(bash)$ kill -9 $$

Jusqu'à présent, l'approche consiste à ne même pas laisser les éléments de l'historique sensibles être écrits sur le disque pour plus de sécurité, car en théorie, les données supprimées d'un support non volatile peuvent toujours être récupérées.

Si, toutefois, les commandes que vous souhaitez supprimer proviennent d'une session précédente, elles auront déjà été ajoutées à la $HISTFILEsortie. L'histoire avec la manipulation des commandes ci - dessus encore que append les autres nouveaux éléments à la $HISTFILE, à la sortie . Pour écraser la vue $HISTFILEavec la vue de la session en cours de tout l' historique, tapez maintenant :

(bash)$  history -w

Bien sûr, pour les éléments d’historique déjà présents sur le disque, l’alternative à l’édition de l’historique avec les history -dcommandes history -w, est l’édition $HISTFILEavec un éditeur de texte.

James Haigh
la source
1
« L'histoire avec Manipuler les commandes ci - dessus encore que append les autres nouveaux éléments à la $HISTFILE, à la sortie . » En fait, ce n'est pas tout à fait vrai. Il semble ajouter uniquement les nouveaux éléments restants qui "ressortent" de la longueur de l'historique d'origine. Par exemple, si je supprime 5 éléments originaux et en ajoute 15 nouveaux, seules les 10 dernières nouvelles sont ajoutées, alors que je m'attendrais à ce que les 15 nouveaux soient ajoutés. Je pense que c'est un bug parce que je ne vois pas en quoi cette fonctionnalité est toujours souhaitable.
James Haigh le
1
Je suppose que bash prend note de la longueur originale. À la fermeture de la session, il ajoute probablement des éléments dont le nombre est supérieur à cette valeur. Si cette valeur était décrémentée chaque fois qu'un élément dont le nombre est inférieur ou égal à celui-ci est supprimé, cela fonctionnerait comme prévu. ;-)
James Haigh le
15

Plusieurs techniques:

Empêcher que des informations sensibles soient stockées dans le fichier historique

Si vous avez entré un mot de passe sur une ligne de commande, assurez-vous que toutes les commandes sont consignées, vous pouvez soit:

  1. Forcer la sortie de la session en cours sans sauvegarder l'historique:

     kill -9 $$

    Cela supprimera toute l'histoire actuelle.

  2. Tapez ↑ (up arrow)la session bash ouverte jusqu'à ce que les informations sensibles soient affichées, puis utilisez les combinaisons de touches de modification de ligne telles que Ctrl+ Wpour supprimer les informations sensibles, puis ↓ (down arrow) jusqu'à ce qu'une nouvelle ligne vide soit affichée avant de taper Enter.

Supprimer les informations sensibles du fichier historique

Si vous réalisez que des informations sensibles sont déjà stockées et que vous souhaitez les supprimer, mais pas tout votre historique:

Une simple sedcommande pourrait faire le travail:

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

mais, en tapant ceci, vous créez une autre ligne d'historique contenant le motif de recherche (informations sensibles) que vous essayez de supprimer. Pour que vous puissiez:

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

Cela fonctionnera head -n1avec l'entrée du terminal. Il semblera que votre terminal est bloqué (il n'y aura pas d'invite); il suffit de taper les informations que vous souhaitez supprimer du fichier. C'est une astuce pour vous permettre d'entrer (une partie de) une commande sans la taper réellement dans la ligne de commande, la rendant ainsi inéligible pour l'inclusion dans l'historique. Ensuite sed, vous utiliserez le texte que vous avez saisi pour rechercher .bash_history et supprimer toutes les lignes contenant les informations sensibles. Remarque: si votre modèle d'informations sensibles contient une ou plusieurs barres obliques, vous devez les échapper avec des barres obliques inverses ou modifiez la sedcommande pour utiliser cette syntaxe afin de spécifier un délimiteur ne figurant pas dans le modèle:

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

Une autre solution pourrait consister à supprimer uniquement les informations sensibles, tout en conservant les commandes contenant les informations. Pour cela, vous pouvez simplement remplacer les informations sensibles par un texte de substitution de votre choix:

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

Supprimer les informations sensibles de tout fichier dans une arborescence spécifique

Enfin, pour être sûr que cela ne restera pas dans un autre fichier oublié:

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

listera tous les fichiers concernés.

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

remplacera toutes les occurrences d’informations sensibles dans tous les fichiers de l’arborescence de répertoires dont le nom est root .. Remarque: même si cette commande utilise xargs -0, elle ne gérera pas les fichiers contenant des nouvelles lignes dans leurs noms.

F. Hauri
la source
11

Recherchez la ligne que vous souhaitez supprimer en appuyant ↑ (up arrow)jusqu'à ce qu'elle apparaisse, puis appuyez sur Ctrl+ U. Cela devrait supprimer la ligne.

Si vous utilisez la historycommande, vous pouvez voir que la ligne a été remplacée par un astérisque.

vicentecarro
la source
2
En fait, je pense que vous devez déplacer le curseur jusqu'à la ligne, appuyer sur Ctrl + U, puis faire glisser le curseur vers le haut ou le bas pour atteindre une autre ligne (éventuellement la ligne vide au bas de la liste). De plus, à proprement parler, la ligne n'a pas été remplacée par un astérisque. La commande a plutôt été effacée et le numéro d’historique a été ajouté avec un *.
G-Man
1
Cela devient beaucoup plus puissant avec Ctrl + R (recherche inversée de l' histoire incrémentale), puis par exemple [Fin], Ctrl + U
sehe
4

Si vous devez supprimer plusieurs lignes en même temps, j'utilise normalement ceci:

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

Si vous devez supprimer la dernière commande, vous pouvez utiliser:

history -d $((HISTCMD-2))
Liaison
la source
2
Cela ressemblait à cela a fonctionné, mais history | grep <string>montre toujours toutes les lignes qu'il prétendait supprimer ...
Brock Hensley
1
Cela effacera les mauvaises lignes de l'historique après avoir supprimé le premier !!
mardi
1
Mais heureusement, il n’imprime que les mauvaises commandes de suppression. Ce qui suit history | grep XYZ | grep -v grep | tac | awk '{print "history -d", $1}'
afficherait les
3

Si vous devez supprimer une plage de lignes de l'historique, la fonction bash suivante peut vous faire gagner du temps:

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 fonction devrait être typiquement ajoutée à $HOME/.bashrc. Pour utiliser la fonction immédiatement, vous devez faire relire le fichier par votre shell en cours d'exécution ( . $HOME/.bashrc). Ensuite, pour supprimer par exemple les commandes 200-210 de l'historique:

$ histdel 200 210

(Remarque: cette question figure parmi les premiers résultats de la recherche si vous recherchez la suppression d'une série de commandes de l'historique bash. Ainsi, bien que ce qui précède dépasse le contenu de la question, il pourrait être utile à certains lecteurs.)

m000
la source
3
Formes alternatives pour la fordéclaration: for n in $(seq "$2" "$1")est stylistiquement préféré par certains, et, si seqcela ne fonctionne pas, essayez for ((n="$2"; n>="$1"; n--)).
Scott
3
history | sed -i 59d

59 est le numéro de ligne. Ne peut pas être plus doux que ça :)

KroKite
la source
3

Essayez juste ceux-ci,

$ history

ceci affichera l'identifiant de l'historique et de la commande, par exemple

.
.
211 ls
212 javac
Bienvenue.java 213 java bienvenue
.
.

utilisation,

$ history -d 211

Ici 211 est l'identifiant de l'histoire. Maintenant, vérifiez ceci en utilisant

$ history

.
.
211 javac
Bienvenue.java 212 java bienvenue
.
.

utilisateur3378188
la source
2

Je sais que cela fait longtemps que cette question n’a pas été posée et qu’il n’ya pas eu de réponse, mais je vais vous montrer ma méthode pour nettoyer mon historique et me déconnecter en même temps.

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

Ce qu'il fait est simple:

  1. history -w : écrit l'historique en cache à l'intérieur "${HISTFILE}"
  2. nano "${HISTFILE}": permettez-moi d’éditer "${HISTFILE}"Vous pouvez utiliser un script sed ou ce que vous voulez pour nettoyer votre"${HISTFILE}"
  3. history -c : efface l'historique en cache pour que cette dernière commande ne soit pas ajoutée.
  4. exit : me déconnecter en ajoutant l'historique mis en cache ... mais il est vide;)

Après cette commande, vous serez déconnecté avec un fichier d’historique vierge. Connectez-vous pour vérifier votre historique;)

J'espère que cela aidera quelqu'un.

ncenerar
la source
1

Vous pouvez également éditer le fichier d’historique directement, par exemple nano .bash_historysi vous êtes dans le shell bash?

Mignon
la source