为什么“erasedups”不能按预期工作?

为什么“erasedups”不能按预期工作?

舞台

sam@x230:~$ grep -E '^VERSION=|^NAME=' /etc/os-release 
NAME="Ubuntu"
VERSION="20.04.5 LTS (Focal Fossa)"
sam@x230:~$ echo ${BASH_VERSINFO[@]}
5 0 17 1 release x86_64-pc-linux-gnu
sam@x230:~$ tail -n $HISTSIZE ~/.bash_history  |grep '^ssh-add -l$' |wc -l
10
sam@x230:~$ grep -i hist .bashrc |egrep -v '^alias|^\s*#'
HISTCONTROL=ignoreboth
shopt -s histappend
HISTSIZE=1000
HISTFILESIZE=20000
sam@x230:~$  sed 's/\(ignoreboth\)$/\1:erasedups/' ~/.bashrc
sam@x230:~$ grep HISTCONTROL ~/.bashrc
HISTCONTROL=ignoreboth:erasedups
sam@x230:~$ export HISTCONTROL=ignoreboth:erasedups
sam@x230:~$ set |grep HIST
HISTCONTROL=ignoreboth:erasedups
HISTFILE=/home/sam/.bash_history
HISTFILESIZE=20000
HISTSIZE=1000

场景一:

sam@x230:~$ echo $HISTCONTROL
ignoreboth:erasedups
sam@x230:~$ ssh-add -l
256 SHA256:5FGaVpklzgSA1r/X8lb4SFaZ9hN0OfQXy+HOWpidcs4 default.sam@x230 (ED25519)
sam@x230:~$ tail -n $HISTSIZE ~/.bash_history  |grep '^ssh-add -l$' |wc -l
10
sam@x230:~$ exit

悲剧结局,在新航站楼:

sam@x230:~$ echo $HISTCONTROL
ignoreboth:erasedups
sam@x230:~$  tail -n $HISTSIZE ~/.bash_history  |grep '^ssh-add -l$' |wc -l
11

专家们

根据man bash

HISTCONTROL
              A colon-separated list of values controlling  how  commands  are
              saved  on  the history list.  If the list of values includes ig‐
              norespace, lines which begin with  a  space  character  are  not
              saved  in  the history list.  A value of ignoredups causes lines
              matching the previous history entry to not be saved.  A value of
              ignoreboth is shorthand for ignorespace and ignoredups.  A value
              of erasedups causes all previous lines matching the current line
              to  be  removed from the history list before that line is saved.
              Any value not in the above list is ignored.  If  HISTCONTROL  is
              unset,  or does not include a valid value, all lines read by the
              shell parser are saved on the history list, subject to the value
              of  HISTIGNORE.  The second and subsequent lines of a multi-line
              compound command are not tested, and are added  to  the  history
              regardless of the value of HISTCONTROL.

批评家们

我预计$HISTSIZEbash 历史记录的最后几行将不再包含重复项(在启动和exitof 的多个周期中bash)。

我的行为或假设哪里出了问题?

注意:我也尝试过设置HISTCONTROL=erasedups,结果相似,即保留重复项(没有测试连续重复项)。

答案1

来自维护者 Chet Chet Ramey 的gnu bash 错误

Erasedups 功能正常工作:它从保存在内存中的历史列表中删除匹配的命令。当 shell 退出时,默认情况下它将当前历史列表附加到历史文件中。如果想强制完全重写历史文件,可以使用history -wat shell exit 来重写。不幸的是,目前没有简单的方法来强制这种rewrite-at-exit行为。

此外,只有当您再次实际使用条目时,它们才会被删除。

因此,您应该发现,如果您:

  1. 启动一个新的外壳
  2. 执行ssh-add -l
  3. 执行history -w

那么ssh-add -l您的~/.bash_history file.

如何解决这个问题?如何定期清除所有重复项?这是另一个问题,但以下内容可能会有所帮助:

相关内容