Votre shell les garde déjà
Chaque commande tapée reste dans l'historique du shell, mais les valeurs par défaut sont petites et le fichier n'est écrit qu'à la sortie du shell. Deux sessions ouvertes en même temps peuvent écraser les lignes l'une de l'autre. Pour bash, ajoutez ceci à ~/.bashrc :
HISTSIZE=100000
HISTFILESIZE=100000
HISTCONTROL=ignoreboth
HISTTIMEFORMAT='%F %T '
shopt -s histappend
PROMPT_COMMAND='history -a'
HISTSIZEetHISTFILESIZEgardent jusqu'à 100 000 lignes en mémoire et dans le fichier.ignorebothignore les lignes répétées et celles qui commencent par une espace.HISTTIMEFORMATajoute la date et l'heure àhistory.histappendethistory -aajoutent chaque commande au fichier tout de suite, donc une connexion perdue ne fait rien perdre. Si votrePROMPT_COMMANDa déjà une valeur, mettezhistory -a;devant.
Pour zsh, le shell par défaut de macOS, mettez ceci dans ~/.zshrc :
HISTFILE=~/.zsh_history
HISTSIZE=100000
SAVEHIST=100000
setopt EXTENDED_HISTORY INC_APPEND_HISTORY HIST_IGNORE_SPACE HIST_IGNORE_DUPS
Faites de même sur les serveurs que vous utilisez le plus. En SSH, l'historique est enregistré sur le serveur, pour l'utilisateur connecté.
Retrouver une commande
Appuyez sur Ctrl-R et tapez n'importe quelle partie de la commande. Ctrl-R à nouveau donne les résultats plus anciens, Entrée lance, une flèche permet de modifier d'abord. Pour voir une liste :
history | grep journalctl
Avec l'horodatage réglé plus haut, la liste montre quand chaque commande a tourné :
1 2026-11-06 15:21:40 echo one
2 2026-11-06 15:21:40 diskfree /tmp
3 2026-11-06 15:21:40 uptime -p # @health
La dernière ligne montre une astuce utile. Un commentaire après # ne fait rien quand la commande tourne, mais il reste dans l'historique. Ajoutez une étiquette comme # @health ou # @deploy, et Ctrl-R puis @health retrouve toutes les commandes marquées ainsi.
Alias et fonctions pour les commandes répétées
Une commande tapée chaque semaine mérite un nom court. Un alias est un texte fixe. Une fonction accepte des arguments :
alias logs='journalctl -u nginx --since "1 hour ago" --no-pager'
diskfree() { df -h "${1:-/}" | tail -n 1; }
diskfree seul vérifie /, et diskfree /var vérifie ce dossier. Vérifiez ce que fait un nom avec type logs. Les alias ne marchent que dans les shells interactifs, donc un script ou ssh server logs ne les trouvera pas. Dans ces cas, utilisez une fonction dans un fichier chargé, ou un petit script dans ~/bin.
Une commande enregistrée par serveur dans la configuration SSH
Pour une commande que vous lancez toujours sur un même serveur, comme suivre un journal, la configuration SSH peut la lancer à la connexion. Mettez ceci dans ~/.ssh/config :
Host web1-logs
HostName web1
RemoteCommand tail -f /var/log/nginx/error.log
RequestTTY yes
ssh web1-logs ouvre alors directement le journal. RequestTTY yes donne un terminal à la commande, donc Ctrl-C fonctionne. Cette entrée n'accepte pas en plus une commande sur la ligne : ssh web1-logs uptime échoue avec Cannot execute command-line and remote command. Remplacez-la quand il le faut :
ssh -o RemoteCommand=none web1-logs uptime
D'autres modèles sont dans le guide du fichier ssh config.
Tout garder dans un fichier qui vous suit
Mettez vos alias et fonctions dans un fichier à part, chargez-le depuis la configuration du shell, et copiez-le sur les serveurs que vous utilisez :
mkdir -p ~/.config/shell
$EDITOR ~/.config/shell/commands.sh
echo '[ -f ~/.config/shell/commands.sh ] && . ~/.config/shell/commands.sh' >> ~/.bashrc
ssh web1 'mkdir -p ~/.config/shell' && scp ~/.config/shell/commands.sh web1:.config/shell/
Ajoutez une fois la même ligne echo au ~/.bashrc du serveur. Garder le fichier dans un dépôt git vous donne son historique et un moyen simple de l'emporter sur une nouvelle machine. Pour l'envoyer sur beaucoup de serveurs à la fois, voir comment exécuter une commande sur plusieurs serveurs.
Ce qu'il ne faut jamais garder
Les fichiers d'historique sont du texte brut. Un mot de passe tapé sur la ligne de commande, comme mysql -pS3cret, y reste pour quiconque peut lire le fichier. Trois façons de tenir les secrets à l'écart :
- Commencez la ligne par une espace. Avec
ignorebothdans bash ouHIST_IGNORE_SPACEdans zsh, elle n'est pas enregistrée. - Ignorez des motifs pour de bon avec
HISTIGNOREdans bash :
HISTIGNORE='*PASSWORD*:*TOKEN*'
- Supprimez une ligne que vous venez de taper. Avec bash 5 ou plus récent, ceci efface la commande précédente :
history -d -2
Cela ne corrige que l'historique en mémoire. Si la ligne est déjà dans le fichier d'historique, supprimez-la aussi là, et changez le mot de passe, car il a pu être copié ailleurs. Mieux encore, laissez le programme demander le mot de passe, avec mysql -p sans rien après, ou lisez les secrets dans un fichier aux droits stricts.
Questions
Où bash enregistre-t-il l'historique des commandes ?
Dans ~/.bash_history, écrit à la sortie du shell, sauf si vous ajoutez history -a à PROMPT_COMMAND. zsh utilise le fichier indiqué par HISTFILE, souvent ~/.zsh_history.
L'historique d'un serveur contient-il mes commandes locales ?
Non. Chaque machine garde son propre historique. Les commandes tapées dans une session SSH sont enregistrées sur le serveur, dans l'historique de l'utilisateur connecté.
Comment empêcher qu'une commande soit enregistrée ?
Commencez-la par une espace quand HISTCONTROL contient ignorespace dans bash, ou quand HIST_IGNORE_SPACE est activé dans zsh. HISTIGNORE peut aussi ignorer des motifs comme *TOKEN*.
Quelle différence entre un alias et une fonction ?
Un alias remplace le premier mot d'une commande par un texte fixe. Une fonction est un petit programme qui accepte des arguments, comme un dossier ou un nom de service.
Sources
- Manuel de Bash : l'historique de Bash
- Manuel de Bash : variables de Bash (HISTCONTROL, HISTIGNORE)
- Manuel de zsh : options d'historique
- ssh_config(5), RemoteCommand