防止重复记录保存在bash历史记录中[closed]

前端之家收集整理的这篇文章主要介绍了防止重复记录保存在bash历史记录中[closed]前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我试图防止bash保存重复的命令到我的历史。这里是我有:
shopt -s histappend
export HISTIGNORE='&:ls:cd ~:cd ..:[bf]g:exit:h:history'
export HISTCONTROL=erasedups
export PROMPT_COMMAND='history -a'

这工作正常,而我登录,.bash_history是在内存中。例如:

$ 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

但是当我重新登录时,我的历史记录文件看起来像这样:

$ 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

我究竟做错了什么?

编辑:从.bashrc中删除shopt和PROMPT_COMMAND行不能解决这个问题。

据我所知,这是不可能做你想要的。我认为这是一个bug,在bash的历史处理,可以改进。
export HISTCONTROL=ignoreboth:erasedups   # no duplicate entries
shopt -s histappend                       # append history file
export PROMPT_COMMAND="history -a"        # update histfile after every command

这将保持内存历史唯一,但虽然它将多个会话的历史记录保存到同一个文件中,但它不会保持文件本身的历史记录本身是唯一的。 history -a将新命令写入文件,除非它与之前一个相同。它不会像内存中的擦除设置那样进行完全重复数据删除

要看到这个行动的蠢,开始一个新的终端会话,检查历史,你会看到重复的条目,说ls。现在运行ls命令,所有重复的ls将从内存中的历史记录中删除,只留下最后一个。当您运行在历史记录文件中重复的命令时,内存历史记录变得更短,但历史记录文件本身继续增长。

我使用自己的脚本根据需要清理历史文件

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

我很想听到更多优雅的方式来做到这一点。

注意:如果通过HISTTIMEFORMAT在历史记录中启用时间戳,脚本将不会工作。

Bash可以改善的情况

>修复历史-a只写入新数据,如果它不匹配内存中的任何历史记录,而不只是最后一个。>在读取文件删除重复数据删除历史记录。一个新的终端中的简单历史记录-w将清除历史文件,而不是上面的愚蠢的脚本。

猜你在找的Bash相关文章