Je sais que cette question n'est pas obscure, car elle est posée ici, continuez à la mettre à jour (et dupliquée ici).
Ce que j'essaie de réaliser est un peu différent. Je n'aime pas l'idée que mon invite réécrive un fichier tous les ls
Je tape (history -a; history -c; history -r
).
Je voudrais mettre à jour le fichier à la sortie. C'est facile (en fait, par défaut), mais vous devez ajouter au lieu de réécrire :
shopt -s histappend
Maintenant, lorsqu'un terminal est fermé, je voudrais que tous les autres qui restent ouverts soient au courant de la mise à jour.
Je préfère le faire sans vérifier via $PS1
à chaque command
que je tape. Je pense qu'il serait préférable de capter une sorte de signal. Comment feriez-vous cela? Si ce n'est pas possible, peut-être un simple cronjob
?
Comment pouvons-nous résoudre ce casse-tête ?
Réponse acceptée :
Des signaux créatifs et engageants, dites-vous ? D'accord :
trap on_exit EXIT
trap on_usr1 USR1
on_exit() {
history -a
trap '' USR1
killall -u "$USER" -USR1 bash
}
on_usr1() {
history -n
}
Mettez ça dans .bashrc
et aller. Cela utilise des signaux pour dire à chaque bash
processus pour vérifier les nouvelles entrées de l'historique lorsqu'un autre sort. C'est assez horrible, mais ça marche vraiment.
Comment ça marche ?
trap
définit un gestionnaire de signal pour un signal système ou l'un des événements internes de Bash. La EXIT
event est toute terminaison contrôlée du shell, tandis que USR1
est SIGUSR1
, un signal sans signification que nous nous approprions.
Chaque fois que le shell se termine, nous :
- Ajouter explicitement tout l'historique au fichier.
- Désactiver le
SIGUSR1
handler et faire en sorte que ce shell ignore le signal. - Envoie le signal à tous les
bash
en cours d'exécution processus du même utilisateur.
Lorsqu'un SIGUSR1
arrive, nous :
- Charger toutes les nouvelles entrées du fichier d'historique dans la liste d'historique en mémoire du shell.
En raison de la façon dont Bash gère les signaux, vous n'obtiendrez pas réellement les nouvelles données d'historique tant que vous n'aurez pas appuyé sur Entrée la prochaine fois, donc cela ne fait pas mieux sur ce front que de mettre history -n
dans PROMPT_COMMAND
. Cependant, cela évite de lire le fichier en permanence lorsque rien ne s'est passé, et il n'y a aucune écriture jusqu'à ce que le shell se termine.
Il y a encore quelques problèmes ici, cependant. La première est que la réponse par défaut à SIGUSR1
est de terminer le shell. Tout autre bash
les processus (exécutant des scripts shell, par exemple) seront tués. .bashrc
n'est pas chargé par des shells non interactifs. A la place, un fichier nommé par BASH_ENV
est chargé :vous pouvez définir globalement cette variable dans votre environnement pour qu'elle pointe vers un fichier avec :
trap '' USR1
dedans pour ignorer le signal qu'ils contiennent (ce qui résout le problème).
Connexe :Commande de terminal pour savoir si un serveur est virtuel ou physique ?Enfin, bien que cela fasse ce que vous avez demandé, la commande que vous obtiendrez sera un peu inhabituelle. En particulier, des éléments d'historique seront répétés dans des ordres différents au fur et à mesure qu'ils sont chargés et enregistrés séparément. C'est essentiellement inhérent à ce que vous demandez, mais sachez que l'historique des flèches vers le haut devient beaucoup moins utile à ce stade. Les substitutions d'historique et autres seront partagées et fonctionneront bien, cependant.