加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

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

发布时间:2020-12-15 16:12:44 所属栏目:安全 来源:网络整理
导读:我试图防止bash保存重复的命令到我的历史。这里是我有: shopt -s histappendexport HISTIGNORE=':ls:cd ~:cd ..:[bf]g:exit:h:history'export HISTCONTROL=erasedupsexport PROMPT_COMMAND='history -a' 这工作正常,而我登录,.bash_history是在内存中。例
我试图防止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将清除历史文件,而不是上面的愚蠢的脚本。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读