Historique des commandes en cas de multiples consoles

Tags: #<Tag:0x00007fb5df76cc48>

Salut tout le monde, j’ai du mal à comprendre comment fonctionne l’historique des commandes quand on a plusieurs fenêtres console ouvertes. Je comprends que chacune a son propre historique, mais, admettons que je les ferme toutes et que j’en rouvre une seule, cette fenêtre récupèrera l’historique d’une seule des fenêtres précédentes. C’est un peu dommage, et du coup je me demande entre autres :

  • Est-ce que ce comportement est valable pour toutes les consoles et bureaux, ou bien c’est une spécificité de mon environnement KDE/Konsole ?
  • Peut-on le modifier ? (genre fusionner tous les historiques ensemble quand on ferme une fenêtre ?)
  • Est-ce que ces réflexions sont une Fausse Bonne Idée (FBI) et si oui pourquoi ?

À vous lire…

Bonjour,
A chaque fois un fichier .bash_history est créé. Si plusieurs consoles, alors plusieurs fichiers.
Seul le premier est repris en compte lors de la réouverture d’une seule fenetre.
Chez moi:

~$ ls -a | grep -i .bash_history
.bash_history
.bash_history-30709.tmp
.bash_history-37148.tmp
.bash_history-41099.tmp
.bash_history-56904.tmp
.bash_history-77775.tmp
.bash_history-96670.tmp
.bash_history-99394.tmp

Je vois plusieurs trucs bizarres :

  1. Quand je tape une commande, le fichier .bash_history ne change pas d’heure, comme si il n’était pas mis à jour en temps réel :
    image
  2. J’ai un seul fichier .bash_history et pas plusieurs comme tu me montres. Ce qui ajoute un peu à ma confusion.

Je pense que KDE/Konsole gère un peu à sa sauce, càd pas tout à fait dans le canon de ce que font d’autres éditeurs. Je vais voir pour trouver de la doc spécifique.

J’ai déjà trouvé la réponse à cette question : le fichier .bash_history n’est enrichi qu’au moment où la fenêtre de terminal est fermée (par exit ou autre moyen).

La commande suivante donne pas mal d’éléments de réponse, mais attention aux flags a, r, n et w, car ils ne sont pas faciles à comprendre :

$ history --help
history: history [-c] [-d décalage] [n] ou history -anrw [nomfichier] ou history -ps arg [arg...]
    Affiche ou manipule l'historique.
    
    Affiche l'historique avec les numéros de lignes en préfixant chaque élément
    modifié d'un « * ».  Un argument égal à N limite la liste aux N derniers éléments.
    
    Options :
      -c        efface la liste d'historique en supprimant tous les éléments
      -d offset efface l'élément d'historique à l'emplacement OFFSET. Un offset négatif
                compte à partir de la fin de la liste de l'historique
    
      -a        ajoute les lignes d'historique de cette session au fichier d'historique
      -n        lit toutes les lignes d'historique non déjà lues depuis le fichier d'historique
                et les ajoute à la liste de l'historique
      -r        lit le fichier d'historique et ajoute le contenu à la liste d'historique
      -w        écrit l'historique actuelle dans le fichier d'historique
    
      -p        effectue un développement de l'historique sur chaque ARG et affiche le résultat
                sans le stocker dans la liste d'historique
      -s        ajoute les ARGs à la liste d'historique comme entrée unique

Comme history jongle en permanence avec le fichier .bash_history et un buffer local à la fenêtre, il est facile de se mélanger les pinceaux.

Ah oui, ça, c’est spécifique à ton interpréteur de commandes. Moi, j’utilise zsh, il gère très bien l’accès concurrent à l’historique.

J’ai ajouté ça dans mon .bashrc pour avoir le même historique dans tous mes terminaux, et ça fonctionne bien, même si ce n’est pas très élégant :

#   ajoute l'history en cours + RAZ history en cours + recharge history
PROMPT_COMMAND="history -a; history -c; history -r; $PROMPT_COMMAND"
1 J'aime

Quelques considérations à avoir en tête pour comprendre la gestion de l’historique :

  • Lorsqu’une console est lancée, elle récupère le contenu de .bash_history comme historique initial, puis initialise un buffer local vide dans lequel elle stocke les commandes saisies au fur et à mesure du travail dans la fenêtre.
  • À la sortie de la console (exit ou fermeture par la croix), le contenu du buffer local (càd uniquement la liste des commandes tapées dans la fenêtre) est copié à la fin du fichier .bash_history.

Exemple facile avec 1 fenêtre

Imaginons que .bash_history contient les commandes :

A
B
exit

Si vous ouvrez une console et entrez la commande :

C

Alors quand vous sortez par exit, .bash_history contient les commandes :

A
B
exit
C
exit

Jusqu’ici c’est facile.

Exemple avec 2 fenêtres

Situation initiale, .bash_history contient les commandes :

A
B
exit

Dans la console 1 vous entrez la commande :

C

L’historique de cette fenêtre numéro 1 contient :

A     (snapshot de .bash_history)
B     (snapshot de .bash_history)
exit  (snapshot de .bash_history)
C     (buffer local)

Et dans la console 2 vous entrez la commande :

D

L’historique de cette fenêtre numéro 2 contient :

A     (snapshot de .bash_history)
B     (snapshot de .bash_history)
exit  (snapshot de .bash_history)
D     (buffer local)

Si vous sortez de la fenêtre 1 par exit, on aura dans .bash_history les commandes :

A
B
exit
C
exit

L’historique de la fenêtre 2 est inchangé (normal) :

A     (snapshot de .bash_history)
B     (snapshot de .bash_history)
exit  (snapshot de .bash_history)
D     (buffer local)

À partir de là, vous avez plusieurs options :

Option 1 : rafraîchir la fenêtre 2 en conservant son propre historique

On peut récupérer les nouveautés du fichier .bash_history (càd les commandes tapées dans la fenêtre 1) à l’aide de la commande history -n :
L’historique de la fenêtre 2 devient :

A          (snapshot de .bash_history)
B          (snapshot de .bash_history)
exit       (snapshot de .bash_history)
D          (buffer local)
history -n (buffer local)
C          (nouveauté récupérée de .bash_history, commande de la fenêtre 1)
exit       (nouveauté récupérée de .bash_history, commande de la fenêtre 1)

Notez que les nouveautés sont récupérées tout à la fin, comme si on venait de les taper dans la fenêtre 2.

Option 2 : réinitialiser la fenêtre 2 en perdant son historique

On peut écraser l’historique local de la fenêtre avec le contenu du fichier .bash_history à l’aide de la commande history -r :
L’historique de la fenêtre 2 devient :

A          (relecture intégrale de .bash_history)
B          (relecture intégrale de .bash_history)
exit       (relecture intégrale de .bash_history)
C          (relecture intégrale de .bash_history)
exit       (relecture intégrale de .bash_history)

Notez que même la commande history -r tapée pour réinitialiser est absente (normal, elle était dans le buffer local qui vient d’être vidé).

En matière d’historique des commandes, il y a aussi sudo qui a son propre historique.

Bonjour,
Que fait l’option histappend (ligne suivante dans bashrc)?
shopt -s histappend

et:
PROMPT_COMMAND='history -a'

Il me semble que ces 2 lignes de mon fichier ~./.bashrc suffisent à faire ce travail. Ai-je tord?

Cette ligne ne fait partie d’un .bashrc standard.

Ensuite tu confonds ton environnement général de l’environnement spécifique du terminal ouvert.

history -a sert à écrire immédiatement dans .bash_history les commandes tapées dans la fenêtre, càd le contenu du petit buffer local, sans attendre de faire exit.

Comme l’instruction est placée dans PROMPT_COMMAND qui est évalué après chaque commande tapée, ça revient à dire que chaque fenêtre met à jour .bash_history tout le temps. Une fenêtre console que l’on ouvre a ainsi dans son historique initial toutes les commandes tapées dans les autres fenêtres déjà ouvertes.

Bonjour,

effectivement, je ne saisissais pas très bien cette différence. Pour moi, toute action passe par une commande lancée depuis un terminal.
Il me semblait que c’était la question initiale de cette discussion posée par Thierz.
merci pour cet éclairage.

@Thierz
merci pour ces précisions.
J’essaie de relire et comprendre la question

La question c’est juste « comment ça marche », vu que le comportement est un peu obscur à première vue… Après chacun y va de sa propre compréhension ou de son explication.