GNU/Linux >> Tutoriels Linux >  >> Linux

Historique BASH tronqué à 500 lignes à chaque connexion

Le problème se résume en fait au comportement différent des shells de connexion et de non-connexion. J'avais défini les variables qui contrôlent l'historique dans mon ~/.bahsrc . Ce fichier n'est pas lu lorsque l'on démarre un shell de connexion, il n'est lu que par des shells interactifs sans connexion (à partir de man bash ):

Lorsque bash est appelé en tant que shell de connexion interactif ou en tant que shell non interactif avec le --login option, il lit et exécute d'abord les commandes du fichier /etc/profile , si ce fichier existe. Après avoir lu ce fichier, il recherche ~/.bash_profile,~/.bash_login , et ~/.profile , dans cet ordre, et lit et exécute les commandes à partir de la première qui existe et est lisible. Le --noprofile L'option peut être utilisée au démarrage du shell pour inhiber ce comportement.

[. . . ]

Lorsqu'un shell interactif qui n'est pas un shell de connexion est démarré, bash lit et exécute les commandes de ~/.bashrc, si ce fichier existe. Cela peut être inhibé en utilisant l'option --norc. L'option de fichier --rcfile forcera bash à lire et exécuter des commandes à partir du fichier au lieu de ~/.bashrc.

Par conséquent, chaque fois que je me connectais, que je tombais sur un tty ou que j'utilisais ssh, le .history le fichier était tronqué car je ne l'avais pas défini à la bonne taille en ~/.profile aussi bien. J'ai finalement réalisé cela et j'ai simplement défini les variables dans ~/.profile où ils appartiennent, au lieu de ~/.bashrc

Donc, la raison pour laquelle mon ~/.history était tronqué parce que je n'avais défini que les variables HISTORY dans un fichier lu par des shells interactifs sans connexion et donc chaque fois que j'exécutais un type de shell différent, les variables étaient ignorées et le fichier était coupé en conséquence.


Ma suggestion est d'utiliser un autre fichier comme HISTFILE , pas le ~/.bash_history par défaut .

Bien que je n'aie pas d'explication analytique, je vais essayer de décrire ce qui m'a conduit à cette suggestion :Si vous utilisez bash comme shell par défaut (de connexion) et utilisez également X (ce qui est très probable) vous avez un bash en cours d'exécution instance juste après la connexion (graphique) :

systemd
 ...
  |-login
  |   `-bash      <<====
  |       `-slim
  |           |-X -nolisten tcp vt07 -auth /var/run/slim.auth
  |           |  `-{X}
  |           `-fluxbox
  |               `-xterm -bg black -fg white
  |                   `-bash
 ...

Je pense que cette instance est un shell de connexion, donc elle ne lit pas votre ~/.bashrc et ne saura donc rien du histappend choix :

coup d'homme(1) :Lorsqu'un shell interactif qui n'est pas une connexion shell est démarré, bash lit et exécute les commandes de /etc/bash.bashrc et ~/.bashrc, si ces fichiers existent. (...)

Tant que ce "shell parent" s'exécute, tout va bien, mais à sa fin (c'est-à-dire l'arrêt du système), il remplacera ~/.bash_history (parce que c'est la valeur par défaut) et gâche votre historique ou le coupe au démarrage du système à (encore une fois par défaut) 500 lignes. (Ou peut-être les deux...)

Il me semble également qu'il ne suffit pas d'inclure la configuration de l'historique dans ~/.bashrc , car cela ne devrait pas être une configuration si rare. Je n'ai aucune explication à cela.

Concernant votre problème, que "les shells de connexion affichent toujours le même comportement", vous pouvez essayer d'inclure la configuration de l'historique également dans ~/.bash_profile :

coup d'homme(1) :Lorsque bash est appelé en tant que shell de connexion interactif ou en tant que shell non interactif avec l'option --login, il lit et exécute d'abord les commandes du fichier /etc/profile, si ce fichier existe. Après avoir lu ce fichier, il recherche ~/.bash_profile, (...)

Malheureusement, je ne peux pas poster une explication plus justifiée avec les détails de mon propre bash config, car je suis un zsh mec...


Étant donné que tous vos paramètres sont dans l'ordre selon la page de manuel et que le fichier d'historique n'est pas limité par sa taille (octets), la seule explication possible à laquelle je puisse penser. Cela a à voir avec la façon dont la coquille meurt.

Selon la référence en ligne, la sortie gracieuse (historique enregistré) ne se produit que lorsque le shell reçoit SIGHUP. Je ne peux pas vraiment expliquer comment votre système propage les signaux lors du redémarrage, mais je soupçonne que votre shell se ferme avec SIGKILL ou SIGPWR.

Cela peut être dû au fait que votre WM s'exécute de manière asynchrone (attendez) et que l'émulateur de terminal généré à partir du WM où bash est reçoit un signal de forçage de sortie autre que SIGHUP. Il se peut également que le système d'exploitation envoie trop rapidement le "final kill" à tous les processus avant que le SIGHUP gracieux initial ne parvienne à accéder au shell via X -> WM -> xterm, peut-être parce que X ou WM prend plus de temps à sortir que il faut que le système d'exploitation soit prêt à descendre.

Je suis en eaux profondes avec ce genre de choses, mais je pense que quelque chose dans ce sens provoque le comportement erratique. J'ai déjà eu ce problème auparavant, et le remède le plus solide est exit dans bash où vous souhaitez conserver l'historique.

J'ai remarqué history -a dans votre question, et je ne vois pas pourquoi cela ne serait pas suffisant pour préserver l'histoire.

Vous pouvez résoudre le problème en déterminant ce qui tue vraiment votre bash et passer à la détermination de l'origine du signal et à la résolution du problème, ou simplement vider l'historique lorsque vous savez quel signal est le dernier (en supposant que les disques sont toujours en ligne d'ici là ):

trap "echo got 1  >/tmp/sig1;  exit" SIGHUP
trap "echo got 2  >/tmp/sig2;  exit" SIGINT
trap "echo got 15 >/tmp/sig15; exit" SIGTERM
 .. and so on...

La capture d'écran incluse illustre ce dont je parle dans les deuxième et troisième paragraphes. La séquence là est je coquillage dans de gauche , tuez la coquille gauche de la droite et cat l'histoire.

coup d'homme

Au démarrage, (...) Le fichier nommé par la valeur de HISTFILE est tronqué, si nécessaire, pour ne pas contenir plus que le nombre de lignes spécifié par la valeur de HISTFILESIZE (+ 500 par défaut).

Si l'option shell histappend est activée (+ défaut ici), les lignes sont ajoutées au fichier d'historique, sinon le fichier d'historique est écrasé.

référence en ligne

3.7.6 Signaux

Lorsque Bash est interactif, en l'absence de pièges, il ignore SIGTERM (pour que "kill 0" ne tue pas un shell interactif), et SIGINT est intercepté et géré (pour que la commande intégrée wait soit interruptible). Lorsque Bash reçoit un SIGINT, il sort de toutes les boucles en cours d'exécution. Dans tous les cas, Bash ignore SIGQUIT. Si le contrôle des tâches est en vigueur (voir Contrôle des tâches), Bash ignore SIGTTIN, SIGTTOU et SIGTSTP.

Les commandes non intégrées lancées par Bash ont des gestionnaires de signaux définis sur les valeurs héritées par le shell de son parent. Lorsque le contrôle des tâches n'est pas activé, les commandes asynchrones ignorent SIGINT et SIGQUIT en plus de ces gestionnaires hérités. Les commandes exécutées à la suite d'une substitution de commande ignorent les signaux de contrôle de tâche générés par le clavier SIGTTIN, SIGTTOU et SIGTSTP.

Le shell se ferme par défaut à la réception d'un SIGHUP. Avant de quitter, un shell interactif renvoie le SIGHUP à tous les travaux, en cours d'exécution ou arrêtés. Les travaux arrêtés reçoivent SIGCONT pour s'assurer qu'ils reçoivent le SIGHUP. Pour empêcher le shell d'envoyer le signal SIGHUP à un travail particulier, il doit être supprimé de la table des travaux avec la fonction intégrée disown (voir Fonctions intégrées de contrôle des tâches) ou marqué pour ne pas recevoir SIGHUP à l'aide de disown -h.

Si l'option de shell huponexit a été définie avec shopt (voir The Shopt Builtin), Bash envoie un SIGHUP à toutes les tâches lorsqu'un shell de connexion interactif se termine.

Si Bash attend qu'une commande se termine et reçoit un signal pour lequel un déroutement a été défini, le déroutement ne sera pas exécuté tant que la commande ne sera pas terminée. Lorsque Bash attend une commande asynchrone via la commande interne wait, la réception d'un signal pour lequel un déroutement a été défini entraînera le retour immédiat de la commande interne wait avec un état de sortie supérieur à 128, immédiatement après quoi le déroutement est exécuté.

capture d'écran de démonstration


Linux
  1. Personnalisation du shell Bash

  2. Analyser l'historique de Bash sous Linux

  3. Comment faire en sorte que la saisie anticipée s'applique à la recherche dans l'historique de Bash (ctrl-r) ?

  4. Histoire mutilée ?

  5. Fonctions dans les variables shell ?

Commande d'historique sous Linux (historique de bash)

.bashrc contre .bash_profile

Qu'est-ce que le shell de connexion sous Linux ?

Utilisation de la fonctionnalité d'historique sur Bash Shell sur le serveur Ubuntu 16.04 LTS

CentOS / RHEL :Comment désactiver l'historique du shell BASH

Comment :Historique Bash/shell illimité ?