Est-il possible de faire écrire à .bash_history immédiatement?

125

J'ouvre souvent des tas de terminaux [pour le moment j'ai 7 ouvert sur cet espace de travail] et je cherche souvent historyavec greppour trouver une commande que je viens d'écrire récemment, mais je ne veux pas traquer le terminal, puis faire défiler vers le haut et traquez-le davantage, etc. Parfois, mes terminaux se ferment sans «sortie» et tout ce que j'ai écrit est perdu [Parfois, j'ai eu besoin de quelque chose que j'avais écrit dans un terminal qui avait été tué].

Alors, y a-t-il moyen de faire en sorte que chaque terminal écrive immédiatement dans .bash_history? ou au moins une fois par minute, ou quelque chose comme ça?

Mat
la source
2
Normalement, j’utilise control-rla recherche inversée dans l’historique des commandes d’une bash. Plus pratique que history | grepsi vous avez besoin d'une expression régulière.
Peter Cordes

Réponses:

93

Une solution simple telle que détaillée dans Mettre à jour l'historique Bash en temps réel .

Il est dit de mettre ces commandes dans la configuration .bashrc:

shopt -s histappend
PROMPT_COMMAND="history -a;$PROMPT_COMMAND"

La première commande change le .historymode de fichier à ajouter. Et le second configure la history -acommande à exécuter à chaque invite du shell. Le -aimmédiatement écrit les lignes actuelles / nouvelles dans le fichier historique.

Connexes pour zsh:

Mario
la source
1
bien ce genre de travaux. J'ai essayé quelques tests supplémentaires et cela ne semble fonctionner que sur la première commande. cela fonctionne-t-il correctement pour vous?
Matt
55

Essayez de mettre ceci dans votre .bashrc:

shopt -s histappend                      # append to history, don't overwrite it
export PROMPT_COMMAND="history -a; history -c; history -r; $PROMPT_COMMAND"

Crédit ici: https://stackoverflow.com/questions/103944/real-time-history-export-amongst-bash-terminal-windows/3055135

history -cefface l'historique de la session en cours. Cela réduira le compteur d'historique du montant de $HISTSIZE. history -rlire le contenu de $HISTFILEet l'insérer dans l'historique de la session en cours. Cela relèvera le compteur d’historique du nombre de lignes $HISTFILE.

Je pense que cela signifie que les commandes sont disponibles presque immédiatement (vous avez un terminal, vous écrivez echo 1, un deuxième terminal echo 2, d'abord echo 3et en appuyant deux fois sur la flèche, vous devriez en avoir echo 2. Vous devez émettre une commande dans un terminal donné pour avoir accès à ce qui a été écrit.

souper
la source
Brillant! Merci. man history
Je me
10
@artfulrobot: Cette commande est bashintégrée, elle est donc décrite dans man bash. Vous pouvez également utiliser help history.
Pabouk
2
Mon zsh est configuré pour fonctionner comme suit: chaque shell suit son historique OWN (et avant cela, l'historique combiné) et chaque commande est ajoutée à l'historique combiné. C’est différent et meilleur que de toujours recharger l’historique pour chaque commande pour chaque shell, car j’ai tendance à avoir un «fil de travail» ou un «job» différent pour chaque terminal shell. Je pense que c'est la différence entre cela avec -ret -cvs juste avoir -a.
Steven Lu
Alors qu'est-ce que vous utilisez exactement? history -c; history -r? J'imagine que c'est mieux pour vous, que ce serait mieux pour moi seulement parfois, j'utilise souvent plusieurs coquillages pour faire un travail, alors je préfère que l'histoire soit combinée autant que possible. En fait, cela n’empêche que cette commande ne soit écrite dans l’histoire qu’après sa fin. En général, lorsque je démarre une session SSH sur un hôte et que je veux en ouvrir un autre pendant que le premier est toujours en cours d'exécution, je dois le ressaisir, car il n'a pas encore été écrit dans l'historique.
sup
Je pense que je ne me suis jamais attardé assez longtemps pour savoir comment faire en sorte que bash suive simultanément des threads parallèles de l'historique (par instance de shell) tout en écrivant immédiatement l'historique dans le fichier d'historique principal. Zsh facilite beaucoup les choses, mais en plus, j'ai défini une fonction zsh pour écrire beaucoup de métadonnées sophistiquées dans un fichier à historique amélioré de ma conception. C'est devenu plutôt indispensable. Quoi qu'il en soit, les mécanismes precmd () et preexec () pour zsh sont des arguments envoyés qui décrivent la commande entrée. Il devient alors trivial de diriger cela vers des fichiers. history -apourrait suffire
Steven Lu
38

J'ai un fichier d'historique volumineux contenant environ 100 000 entrées et les variantes qui effacent la liste d'historique et lisent l'intégralité du fichier d'historique (à l'aide de history -cet history -r) introduisent un délai notable ( environ 0,2 seconde) avant l'affichage de l'invite. L'utilisation de history -nsorte que seules les nouvelles lignes du fichier d'historique soient lues est plus rapide:

shopt -s histappend
PROMPT_COMMAND='history -a;history -n'

PROMPT_COMMAND ne doit pas être exporté car il s’agit d’une variable shell.

nisetama
la source
Brillant! Pas plus d'histoire perdue lorsque la connexion est abandonnée!
Tobia
C'est merveilleux En ajoutant au fichier et en lisant à partir du fichier, il partagera l’historique entre plusieurs terminaux.
wisbucky
3

Une note pour toutes les autres réponses (qui sont fondamentalement la même chose):

Mettre PROMPT_COMMAND="history -a;$PROMPT_COMMAND"en .bashrc(ou amis) suffit.

En outre, vous pouvez exécuter manuellement history -achaque fois que vous souhaitez "capturer" l'historique de la session en cours.

La commande shopt -s histappendn'est pas nécessaire car elle history -aajoute toujours de nouvelles lignes au fichier et ne l'écrase jamais. Aussi, au moins à partir de Bash 4, histappendest le comportement par défaut.

Guss
la source
Sur mon mac 10.13.6, il semblait que cela ne fonctionnait pas sans le shopt -s histappend. Notez aussi que je l'ai ajouté à~/.bash_profile
ubershmekel
Probablement, un autre paramètre de votre système est désactivé histappend, car il s'agit du comportement par défaut. Je le chercherais, mais je n'ai pas accès à un Mac.
Guss