Linux / Commande history : rechercher et gérer l’historique Bash

La commande history dans Bash affiche les commandes précédentes retenues par le shell actuel avec leurs numéros et est utilisée pour rechercher, réexécuter, supprimer des éléments ou synchroniser avec le fichier d'historique. Pour afficher uniquement les commandes les plus récentes, utilisez history 20 ; pour rechercher une chaîne spécifique, utilisez history | grep 'systemctl' ; et pour trouver rapidement des commandes en tapant, utilisez Ctrl+r.

history est une commande intégrée dans Bash. L'explication dans cet article est basée sur Bash, et d'autres shells comme Zsh ou Fish peuvent avoir des fichiers d'historique et des paramètres différents.

Qu'est-ce que la commande history ?

Bash stocke les commandes entrées par l'utilisateur dans un shell interactif dans une liste d'historique en mémoire. history est une commande qui vous permet de voir et de modifier cette liste et de lire ou d'écrire le fichier d'historique indiqué par HISTFILE.

Le fichier d'historique par défaut est généralement ~/.bash_history. Lorsque Bash démarre, il lit ce fichier pour créer la liste d'historique en mémoire, et lorsque le shell se termine normalement, il enregistre l'historique actuel dans le fichier. Le comportement détaillé peut être trouvé dans la documentation GNU Bash History Facilities.

L'historique des commandes est une fonctionnalité de commodité, et non un journal d'audit de sécurité. Les utilisateurs peuvent supprimer des entrées, et si le shell se termine de manière anormale ou si l'enregistrement de l'historique est désactivé, il se peut qu'il ne soit pas sauvegardé.

Utilisation de base

Lancer la commande sans options affichera l'historique de la session Bash actuelle avec des numéros.

history

Un exemple de sortie est le suivant.

  241  apt update
  242  systemctl status ssh
  243  journalctl -u ssh
  244  history

Pour ne voir qu'une portion récente de l'historique, comme les 20 dernières entrées, spécifiez un numéro.

history 20
Format Fonction Points à noter
history n Afficher les dernières n entrées Il est basé sur la liste en mémoire du shell actuel.
history -c Supprimer l'ensemble de la liste d'enregistrements actuelle L'état des autres sessions shell et fichiers doit être considéré séparément.
history -d number Supprimer l'élément spécifié Vérifiez d'abord si le numéro à supprimer est correct.
history -a Ajouter de nouveaux éléments de cette session à la fin du fichier HISTFILE doit être défini.
history -n Ajouter de nouvelles entrées du fichier à la liste actuelle Utile lors de l'importation d'enregistrements ajoutés dans une autre session.
history -r Ajouter l'ensemble du fichier d'historique à la liste actuelle Peut dupliquer des entrées déjà existantes.
history -w Écraser le fichier d'historique avec la liste actuelle Si plusieurs terminaux sont ouverts, cela peut affecter l'historique des autres sessions.
history -p expression N'affichez que les résultats de l'expansion de l'historique Il est utile pour vérifier le résultat étendu de ! avant l'exécution.
history -s command Ajouter à l'historique sans exécuter la commande Elle apparaît comme la dernière entrée de la liste d'historique actuelle.

Pour les définitions exactes et les statuts de retour de chaque option, consultez la documentation GNU Bash History Builtins.

Recherche des commandes précédentes

Filtrage de la liste avec grep

Si vous voulez voir uniquement les lignes dans l'historique qui contiennent une chaîne spécifique, utilisez grep avec un pipe.

history | grep 'systemctl'

Pour ignorer la casse, utilisez grep -i.

history | grep -i 'nginx'

Cette méthode est pratique pour vérifier les résultats, mais la commande de recherche actuelle incluse dans la sortie peut également apparaître dans les résultats.

Recherche en tapant avec Ctrl+r

Si Bash utilise le mode d’édition Emacs par défaut, vous pouvez effectuer une recherche incrémentale inversée des commandes précédentes avec Ctrl+r. Chaque fois que vous tapez un caractère à rechercher, l'entrée correspondante la plus récente s'affiche, et appuyer à nouveau sur Ctrl+r passe au résultat plus ancien suivant.

  • Enter : Exécute la commande affichée.
  • Flèches gauche/droite : Terminer la recherche et éditer la commande.
  • Ctrl+g : Annule la recherche et revient à l'entrée originale.

Il est prudent de terminer la recherche en utilisant les touches fléchées juste avant l'exécution pour revoir la commande et ses arguments. La méthode de recherche est expliquée dans la documentation GNU Readline sur la recherche dans l'historique des commandes.

Réexécuter la commande précédente

Expansion de l'historique en utilisant les points d'exclamation

Dans Bash interactif, vous pouvez utiliser l'expansion de l'historique en commençant par ! pour rappeler les commandes précédentes.

Expression Signification Exemple
!! Commande précédente sudo !! ajoute sudo devant la commande précédente.
!125 Commande avec le numéro d'historique 125 Vous pouvez vérifier le numéro à partir de la sortie de history.
!-3 La troisième commande précédente depuis la position actuelle Sélectionner les commandes récentes par position relative.
!ssh La commande la plus récente commençant par ssh S'il y a plusieurs commandes avec le même préfixe, un élément inattendu peut être sélectionné.
!?nginx? La commande la plus récente contenant nginx Rechercher une chaîne au milieu de la commande.
^old^new^ Remplacer la première chaîne correspondante de la commande précédente et exécuter Elle est utilisée pour corriger de petites fautes de frappe et exécuter à nouveau.

L'expansion de l'historique est activée par défaut dans Bash interactif, mais elle n'est pas effectuée par défaut dans les scripts shell non interactifs. Pour la syntaxe détaillée, se référer à la documentation de l'expansion de l'historique GNU Bash.

Vérifiez le résultat de l'expansion avant d'exécuter

!number et !string peuvent exécuter immédiatement la commande trouvée, soyez donc particulièrement prudent s'il y a des commandes de suppression, de changement de permissions ou d'arrêt du système dans l'historique. Si vous passez l'expression à history -p entre guillemets, vous pouvez vérifier le résultat de l'expansion sans l'exécuter.

history -p '!!'
history -p '!ssh'

Dans Bash utilisant Readline, définir l'option suivante permet d'afficher d'abord le résultat de l'expansion de l'historique dans le tampon d'édition sans exécution immédiate.

shopt -s histverify

Dans des environnements multi-terminaux où les numéros peuvent changer facilement, il est souvent plus sûr de rechercher avec Ctrl+r, de vérifier le contenu, puis d'exécuter.

Supprimer l'historique des commandes

Supprimer une entrée spécifique

Tout d'abord, vérifiez le numéro avec history, puis supprimez l'entrée correspondante de la liste d'historique de la mémoire en utilisant l'option -d.

history -d 125

Si le Bash actuel prend en charge la suppression par plage, vous pouvez également spécifier un numéro de début et de fin.

history -d 120-125

Pour refléter les résultats de la suppression dans le fichier d'historique actuel, vous pouvez vérifier la liste, puis exécuter history -w. Cependant, soyez conscient que d'autres sessions de terminal pourraient plus tard réécrire l'historique précédent dans le fichier lors de leur fermeture, donc assurez-vous que plusieurs sessions ne sont pas ouvertes.

Supprimer toute la liste actuelle

L'option -c efface toutes les entrées de la liste d'historique dans la mémoire du shell actuel.

history -c

Pour mettre à jour le fichier d'historique afin qu'il corresponde à la liste actuelle, vous devez comprendre comment history -w fonctionne avant de l'utiliser. La suppression de l'historique ne concerne que l'historique du shell et ne supprime pas les journaux système, les journaux d'audit, les sauvegardes ou l'historique d'autres terminaux.

Fichier d’historique et sessions multiples de terminal

Bash a une liste d'historique mémoire séparée pour chaque shell en cours d'exécution. Par défaut, les commandes exécutées dans un autre terminal peuvent ne pas apparaître immédiatement dans le history du terminal actuel.

Commande Comportement entre le fichier d'historique et la session en cours
history -a Ajoute au fichier les nouvelles entrées de l'historique de la session en cours qui n'ont pas encore été enregistrées dans le fichier.
history -n Ajoute de nouvelles lignes du fichier d'historique que la session actuelle n'a pas encore lues à la liste de mémoire.
history -r Ajoute l'intégralité du contenu du fichier d'historique à la fin de la liste de mémoire actuelle.
history -w Écrase le fichier d'historique avec l'intégralité de la liste de mémoire actuelle.

Pour importer un nouvel historique depuis un autre terminal, ajoutez-le d'abord au fichier dans ce terminal avec history -a, puis lisez-le dans le terminal actuel avec history -n.

history -a
history -n

Vous pouvez utiliser l'option histappend pour ajouter de nouvelles entrées au lieu d'écraser le fichier d'historique lorsque le shell se termine.

shopt -s histappend

Pour continuer à utiliser ce paramètre, ajoutez-le au ~/.bashrc de l'utilisateur. Il existe également un moyen de définir PROMPT_COMMAND pour qu'il se synchronise automatiquement à chaque invite depuis plusieurs terminaux, mais vous ne devez pas l'écraser sans vérifier la valeur actuelle, car les paramètres ou programmes existants peuvent utiliser cette variable.

Variables Bash liées à l’historique

Variable Rôle
HISTFILE Le chemin vers le fichier où l'historique est stocké. La valeur par défaut la plus courante est ~/.bash_history.
HISTSIZE Le nombre maximum de commandes à conserver dans la mémoire de l'historique du shell actuel.
HISTFILESIZE Limite la taille maximale du fichier d'historique en termes de lignes.
HISTCONTROL Définissez des règles de stockage, telles que ne pas enregistrer les commandes qui commencent par un espace ou les commandes dupliquées consécutives.
HISTIGNORE Spécifiez les motifs de commande à exclure de l'enregistrement, séparés par des deux-points.
HISTTIMEFORMAT Spécifiez le format de date et d'heure à afficher dans la sortie history.

Les paramètres suivants fixent la limite en mémoire à 5 000 commandes et la taille du fichier à 10 000 lignes. Ils excluent les commandes commençant par une espace, éliminent les doublons selon les règles indiquées et affichent les horodatages disponibles. Une commande sur plusieurs lignes n’équivaut pas nécessairement à une seule ligne du fichier.

HISTSIZE=5000
HISTFILESIZE=10000
HISTCONTROL=ignoreboth:erasedups
HISTTIMEFORMAT='%F %T '
shopt -s histappend

Ces réglages changent la politique de conservation de l’historique. Avant de modifier ~/.bashrc, conservez une copie du fichier et notez les valeurs actuelles. Pour revenir en arrière, restaurez les lignes modifiées puis ouvrez une nouvelle session. Les entrées déjà supprimées ne sont pas restaurées par ce changement.

Pour appliquer de manière continue, ajoutez les paramètres ci-dessus à ~/.bashrc, puis démarrez une nouvelle session Bash ou rechargez le fichier de configuration.

source ~/.bashrc

HISTCONTROL=ignoreboth applique à la fois ignorespace et ignoredups. erasedups supprime les entrées précédentes identiques aux nouvelles commandes de la liste d'historique. Des règles détaillées pour chaque variable peuvent être trouvées dans la documentation des variables GNU Bash.

Historique des commandes et sécurité

Si vous saisissez des mots de passe, des clés API, des jetons ou le contenu de clés privées comme arguments de ligne de commande, ils peuvent être exposés non seulement dans l'historique du shell, mais aussi dans les informations du processus en cours ou d'autres journaux. Pour les informations sensibles, il est recommandé de ne pas les saisir directement sur la ligne de commande mais d'utiliser l'entrée standard fournie par le programme, un magasin d'identifiants sécurisé ou un fichier de configuration avec un accès restreint.

Si ignorespace est défini dans HISTCONTROL, les commandes qui commencent par un espace peuvent être exclues de l'historique. Vérifiez que ce réglage est actif : il ne protège pas les autres journaux ni les informations de processus et ne suffit pas à sécuriser des secrets.

printf '%s\n' "$HISTCONTROL"
printf '%s\n' "$HISTFILE"

Même si vous supprimez des entrées avec history -d ou history -c, les mêmes informations peuvent rester dans d'autres sessions de shell, sauvegardes, journaux d'audit et journaux d'application. Si des identifiants sont exposés, ne vous contentez pas de supprimer l'historique ; vous devez invalider le mot de passe ou le jeton affecté et en émettre un nouveau.

Problèmes courants

Les dernières commandes d'un autre terminal ne sont pas visibles

Chaque session Bash utilise une liste de mémoire indépendante. Après avoir exécuté history -a dans le terminal où les commandes ont été lancées, essayez d'exécuter history -n dans le terminal que vous souhaitez vérifier. À long terme, vous pouvez consulter histappend et les paramètres d'initialisation du shell.

L'historique a disparu après la fermeture du terminal

HISTFILE peut être vide ou vous n'avez peut-être pas la permission d'écrire dans le fichier d'historique, ou HISTSIZE ou HISTFILESIZE peuvent être définis à 0. Si le shell a été terminé de force, le processus de sauvegarde de l'historique à la sortie peut ne pas avoir été effectué.

Pourquoi les numéros d’historique changent-ils ?

Les numéros d'historique ne sont pas des identifiants fixes mais la position dans la liste de mémoire actuelle. Si vous supprimez des entrées ou rechargez le fichier pour fusionner l'historique d'une autre session, les numéros peuvent changer. Il est plus sûr de rechercher et de vérifier le contenu de la commande plutôt que de se souvenir et d'exécuter d'anciens numéros.

Les mêmes paramètres peuvent-ils être utilisés dans Zsh ou Fish ?

Ils ne peuvent pas être appliqués tels quels. Même s'il existe une fonction nommée history, le fichier d'historique et la façon dont il se synchronise avec les variables d'environnement diffèrent pour chaque shell. Identifiez le shell réellement utilisé et consultez sa documentation. La variable SHELL indique généralement le shell de connexion configuré ; elle ne prouve pas quel interpréteur exécute la session actuelle.

Résumé

history dans Bash peut être utilisé non seulement pour afficher les commandes précédentes, mais aussi pour supprimer des entrées spécifiques, lire/écrire le fichier d'historique et synchroniser entre les sessions. Pour la recherche quotidienne, history | grep et Ctrl+r sont pratiques, et lors de la réexécution en utilisant l'expansion de l'historique, il est nécessaire de vérifier d'abord le contenu de la commande.

Pour modifier la quantité et la méthode de stockage des enregistrements, consultez ensemble HISTSIZE, HISTFILESIZE, HISTCONTROL, HISTTIMEFORMAT et histappend.