Verhindern, dass Duplikate im Bash-Verlauf gespeichert werden [geschlossen]

Ich versuche zu verhindern, dass Bash doppelte Befehle in meinem Verlauf speichert. Hier ist was ich habe:

shopt -s histappend
export HISTIGNORE='&:ls:cd ~:cd ..:[bf]g:exit:h:history'
export HISTCONTROL=erasedups
export PROMPT_COMMAND='history -a'

Dies funktioniert gut, wenn ich angemeldet bin und .bash_history im Arbeitsspeicher ist. Zum Beispiel:

$ history
    1 vi .bashrc
    2 vi .alias
    3 cd /cygdrive
    4 cd ~jplemme
    5 vi .bashrc
    6 vi .alias

$ vi .bashrc

$ history
    1 vi .alias
    2 cd /cygdrive
    3 cd ~jplemme
    4 vi .alias
    5 vi .bashrc

$ vi .alias

$ history
    1 cd /cygdrive
    2 cd ~jplemme
    3 vi .bashrc
    4 vi .alias

$ exit

Wenn ich mich wieder einlogge, sieht meine Verlaufsdatei so aus:

$ history
    1 vi .bashrc
    2 vi .alias
    3 cd /cygdrive
    4 cd ~jplemme
    5 vi .bashrc
    6 vi .alias
    7 vi .bashrc
    8 vi .alias

Was mache ich falsch?

BEARBEITEN: Das Entfernen der Zeilen shopt und PROMPT_COMMAND aus .bashrc behebt das Problem nicht.

Soweit ich weiß, ist es nicht möglich, das zu tun, was Sie wollen. Ich sehe das als Fehler in der Historienverarbeitung von bash, der verbessert werden könnte.

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

Dadurch bleibt der Speicherverlauf im Speicher eindeutig, aber während der Verlauf von mehreren Sitzungen in derselben Datei gespeichert wird, bleibt der Verlauf in der Datei selbst nicht eindeutig. history -a schreibt den neuen Befehl in die Datei, es sei denn, er entspricht dem unmittelbar davor. Es wird keine vollständige Deduplizierung durchgeführt, wie dies bei den Löschungen im Speicher der Fall ist.

Starten Sie eine neue Terminalsitzung, überprüfen Sie die Historie, und Sie sehen wiederholte Einträge, beispielsweise ls. Führen Sie nun den Befehl ls aus, und alle duplizierten ls werden aus der Historie entfernt, wobei nur die letzten verbleiben. Die Historie im Arbeitsspeicher wird kürzer, wenn Sie Befehle ausführen, die in der Protokolldatei doppelt vorhanden sind. Die Protokolldatei selbst wächst jedoch weiter.

Ich verwende mein eigenes Skript, um die Verlaufsdatei bei Bedarf zu bereinigen.

# 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
}

Ich würde gerne elegantere Wege dazu hören.

Hinweis: Das Skript funktioniert nicht, wenn Sie den Zeitstempel im Verlauf über HISTTIMEFORMAT aktivieren.

Bash kann die Situation dadurch verbessern

> Historie -a korrigieren, um nur neue Daten zu schreiben, wenn sie nicht mit der Historie im Speicher übereinstimmen, nicht nur mit der letzten.
> Deduplizierung des Verlaufs beim Lesen von Dateien, wenn die Löscheinstellungen eingestellt sind. Eine einfache History -w in einem neuen Terminal würde dann die History-Datei anstelle des dummen Skripts oben bereinigen.

Ursprüngliche URL:https://stackoverflow.com/questions/338285/prevent-duplicates-from-being-saved-in-bash-history

Zitieren Sie bitte die URL dieses Artikels: Verhindern, dass Duplikate im Bash-Verlauf gespeichert werden [geschlossen]