Perte d'historique Bash lors de l'utilisation de histappend

18

J'aime garder beaucoup d'histoire, donc je me suis histappendinstallé .bashrc. La plupart du temps, tout fonctionne bien, avec une histoire constituée de nombreux obus. Cependant, de temps en temps, je démarre un nouveau shell et je constate que j'ai perdu tout l'historique - et il ne contient souvent que certaines des commandes du dernier shell à quitter (c'est-à-dire qu'il ne s'agit pas simplement d'écraser au lieu d'ajouter) ). Pour cette raison, je soupçonne que cela se produit à la sortie du shell, plutôt que par un autre processus tuant le .bash_historyfichier. À l'appui de cette conclusion, j'ai des numéros de commande d'historique dans mon invite et je ne les ai jamais vus sauter.

Quelqu'un a déjà rencontré un problème similaire? Ou même juste des suggestions sur la façon de dépister le problème?

Cascabel
la source

Réponses:

13

Désolé de répondre à ma propre question, mais aucune des autres réponses ne résout vraiment le problème.

J'ai finalement compris que cela ne se produit que lors de la fermeture gnome-terminal(fichier> exit, le bouton 'x', alt + F4), et même généralement uniquement lors de la fermeture de plusieurs terminaux en succession rapide. Cela ne se produit jamais lorsque vous utilisez ctrl-D pour fermer le shell, laissant le terminal suivre.

Si je peux le définir assez bien, je déposerai un rapport de bogue sur gnome-terminal. En attendant, cela aidera peut-être d'autres personnes qui arrivent ici de Google!

Cascabel
la source
10

Je ne sais pas pourquoi cela se produit, mais vous pouvez peut-être contourner le problème en forçant bash à écrire dans son fichier d'historique chaque fois qu'il affiche une invite:

PROMPT_COMMAND="history -a; history -n"

Cela écrira (-a) puis relira (-n) le fichier historique chaque fois que bash vous demandera la commande suivante. Avantage supplémentaire: vous obtiendrez la commande X dans le shell 1 dans l'histoire du shell 2.

innaM
la source
Ne fonctionne pas sur GNU bash, version 3.00.15 (1) -release (i686-redhat-linux-gnu)
David Mackintosh
2
Pouvez-vous expliquer ce que signifie «ne fonctionne pas»?
innaM
3
L'avantage supplémentaire que vous citez est dans de nombreux cas un inconvénient. Ce n'est pas le comportement que je recherche, car j'exécute peut-être deux tâches complètement distinctes dans des coquilles distinctes, et je ne veux pas mélanger leur histoire. Cela n'aiderait probablement rien non plus. Lorsque l'historique disparaît, il supprime le contenu de .bash_history - je ne m'attends pas à ce qu'ils importent qu'ils aient été écrits à la sortie du shell ou par PROMPT_COMMAND.
Cascabel
5
history -nest feuilleté. C'est plus fiable à faire history -a; history -c; history -r. Pour expliquer cela, je vais d'abord noter que cela history -afait la bonne chose - votre .bash_historycontiendra toutes vos commandes que vous avez tapées, dans l'ordre que vous les avez tapées - en supposant que vous exécutez history -aaprès chaque commande. Le défi consiste à synchroniser l'idée du shell sur l'historique avec le fichier .bash_history. C'est facile avec -cet -r, le problème est qu'il peut être lent s'il est volumineux. -npeut casser car il identifie de manière incorrecte les lignes qui sont nouvelles. (Je suis à court d'espace ici!)
Aaron McDaid
4
(... si vous utilisez -n) Imaginez que vous exécutez une commande shell en 1: ls. Ensuite, dans un autre shell, Shell Two, vous exécutez cd. Maintenant, l'historique dans le .bash_history est correct à cause du history -adans votre PROMPT_COMMAND- il contiendra ls \n cd \n. Ensuite, vous revenez à shell One et tapez pwd. Shell One pense qu'il n'y avait que la commande n dans l'historique ( ls). Maintenant, il pense qu'il y a deux commandes ( lset pwd) dans l'histoire. Quand vous le faites, -nil pense (j'ai deux commandes dans mon histoire, et il y a deux commandes dans .bash_history, donc je suis à jour.)
Aaron McDaid
3

D'après mon expérience, les shells ont mis à jour le fichier d'historique au moment de la sortie. Ainsi, "l'histoire" initiale d'un obus dépendait de la vision de l'histoire la plus récente du shell.

Le résultat de ceci est que vous pouvez obtenir des commandes qui vont et viennent à partir de l'historique, selon la façon dont les autres shells ont démarré et arrêté.

David Mackintosh
la source
2
Je comprends très bien comment le fichier historique est écrit - c'est pourquoi j'ai spécifié dans ma question que j'utilise histappend. Le problème n'est pas un contenu inattendu, mais une perte totale de contenu précédemment stocké.
Cascabel
Cela explique pourquoi je perdais mon histoire ...
B Seven
1

J'ai déjà vu cela se produire auparavant, mais c'était un problème avec des erreurs de disque qui se produisaient avec une fréquence croissante. Je lancerais une analyse sur le lecteur. S'il s'avère que le lecteur est correct, je vérifierais si ce fichier ne dépasse pas une limite d'historique de shell arbitraire.

Quelque chose qui pourrait empêcher cela de se produire serait de continuer à élaguer le fichier à 80 lignes ou à autant de commandes que vous souhaitez que l'historique soit.

Axxmasterr
la source
Je n'ai pas d'accès root sur la machine sur laquelle cela se produit, mais je suis assez confiant que le lecteur est correct. Mon répertoire personnel est stocké sur un serveur dans notre laboratoire (beaucoup de RAID, je crois) et monté sur nfs. Qu'entendez-vous par «limite d'historique de shell arbitraire»? Tout cela se passe bien en dessous de HISTSIZE et HISTFILESIZE, et bien que j'aie tous les deux réglé grand, ils sont bien en dessous du intbash les stocke sous.
Cascabel
Je dois dire que l'entrée de David Mackintosh est probablement ce qui se passe.
Axxmasterr
1
Je suis tout à fait sûr que non. Je ne devrais jamais me retrouver avec seulement deux commandes dans mon historique, lorsque le dernier shell à quitter avait une douzaine de commandes, le fichier historique en avait plusieurs centaines et HISTSIZE / HISTFILESIZE sont définis sur 10000.
Cascabel