50 votes

Empêcher les doublons d'être enregistrés dans l'historique de bash

J'essaie d'empêcher bash d'enregistrer des commandes en double dans mon histoire. Voici ce que j'ai:

Cela fonctionne très bien pendant que je suis connecté et .bash-histoire est dans la mémoire. par exemple:

Mais quand je me connecte, mon fichier d'histoire ressemble à ceci:

Qu'est-ce que je fais de mal ?

EDIT: Supprimer les lignes shopt et PROMPT-COMMAND de .bashrc ne résout pas le problème.

39voto

raychi Points 199

Autant que je sache, il n'est pas possible de faire ce que vous voulez. Je vois cela comme un bug dans un bash de l'histoire du traitement qui pourrait être amélioré.

export HISTCONTROL=ignoreboth:erasedups   # no duplicate entries
shopt -s histappend                       # append history file
export PROMPT_COMMAND="history -a"        # update histfile after every command

Cela vous permettra de garder en mémoire l'histoire unique, mais, alors qu'il n'économise de l'histoire à partir de plusieurs sessions dans le même fichier, ça ne se garde pas l'histoire dans le fichier lui-même unique. history -a écrira la nouvelle commande dans le fichier, sauf si c'est la même que celle juste avant. Il ne sera pas faire des doublons comme l' erasedups paramètre n'en mémoire.

Pour voir cette bêtise dans l'action, démarrer une nouvelle session de terminal, d'examiner l'histoire, et vous verrez les entrées répétées, dire ls. Maintenant, exécutez l' ls de commande, et tous les dupliqué ls sera supprimée à partir de l'histoire dans la mémoire, ne laissant que le dernier. La mémoire, l'histoire devient plus courte que vous pouvez exécuter des commandes qui sont en double dans le fichier d'historique, mais le fichier d'historique lui-même continue de croître.

J'utilise mon propre script pour nettoyer l'historique de la demande.

# remove duplicates while preserving input order
function dedup {
   awk '! x[$0]++' $@
}

# removes $HISTIGNORE commands from input
function remove_histignore {
   if [ -n "$HISTIGNORE" ]; then
      # replace : with |, then * with .*
      local IGNORE_PAT=`echo "$HISTIGNORE" | sed s/\:/\|/g | sed s/\*/\.\*/g`
      # negated grep removes matches
      grep -vx "$IGNORE_PAT" $@
   else
      cat $@
   fi
}

# clean up the history file by remove duplicates and commands matching
# $HISTIGNORE entries
function history_cleanup {
   local HISTFILE_SRC=~/.bash_history
   local HISTFILE_DST=/tmp/.$USER.bash_history.clean
   if [ -f $HISTFILE_SRC ]; then
      \cp $HISTFILE_SRC $HISTFILE_SRC.backup
      dedup $HISTFILE_SRC | remove_histignore >| $HISTFILE_DST
      \mv $HISTFILE_DST $HISTFILE_SRC
      chmod go-r $HISTFILE_SRC
      history -c
      history -r
   fi
}

J'aimerais entendre plus élégante des façons de le faire.

Remarque: le script ne fonctionne pas si vous activez l'horodatage dans l'histoire via HISTTIMEFORMAT.

Bash peut améliorer la situation en

  1. correctif history -a seulement écrire de nouvelles données si elle ne correspond pas à une histoire dans la mémoire, et pas seulement le dernier.
  2. de déduplication de l'histoire lorsque les fichiers sont en lecture si erasedups paramètre est défini . Un simple history -w dans un nouveau terminal serait alors de nettoyer le fichier de l'historique au lieu de la bête script ci-dessus.

7voto

hop Points 15423

Le problème est certainement le `` . Testé et confirmé sur mon système.

Mon environnement pertinent est :

Maintenant que j'y pense, le problème est probablement avec le . devrait écrire l'histoire actuelle sans aucun double, alors utilisez que si vous n'avez pas l'esprit les questions de concurrence.

5voto

Robert Gamble Points 41984
export HISTCONTROL=ignoreboth

3voto

Venu Anuganti Points 11

Voici ce que j'utilise.

et de travail

2voto

J.F. Sebastian Points 102961

Il ne fonctionne pas:

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X