从Bash历史记录文件中删除某行


Answers:


108

您需要注销然后重新登录或运行,history -a以便将当前历史记录提交到磁盘。

然后编辑文件~/.bash_history


19
如果设置了HISTFILE环境变量,则历史记录文件不是〜/ .bash_history,而是$ {HISTFILE}。
Karolos

20
退出外壳程序时,会将条目写入历史记录文件。因此,输入要删除的命令后,您需要注销并重新登录,或者使用'history -d xxxx'将其从当前的Shell会话中删除。
2014年

3
但是您将如何删除编辑历史文件的记录?
chiliNUT 2014年

5
@chiliNUT:只需vim ~/.bash_history使用空格启动命令(例如)即可;以空格开头的命令通常不会被记录(请参阅参考资料$HISTCONTROL)。
cYrus

我认为分发的情况并非如此,但总的来说这是有道理的
chiliNUT14年

149

您可以通过以下两个步骤使用命令行从历史文件中删除:

  1. 键入history -d <line_number>会从内存中的历史记录中删除指定的行。
  2. 键入history -w会将当前的内存历史记录写入~/.bash_history文件。

这两个步骤一起从内存历史记录.bash_history文件中永久删除该行。


7
如何history -w从历史记录中删除最后一个?
KrIsHnA 2015年

@KrIsHnA手动编辑〜/ .bash_history
Alexander Myshov

5
或者在其前面添加一个空格以防止添加它,例如@tao的答案
标记

为了找到<line_number>history | grep [unwanted_content]包含所有行的列表[unwanted_content](如密码)。
AvL

如何删除多行(特定)(按ID)?
Pathros

39

首先要防止将命令添加到历史记录中,请确保环境变量HISTCONTROL在其以冒号分隔的值中包含value ignorespace,例如(添加到.bashrc):

$ export HISTCONTROL=ignorespace

这样可以防止将任何带有前导空格的命令添加到历史记录中。然后,您可以运行以下命令彻底清除历史记录

$  history -c -w
  ^-- additional space character

32

首先,如果您要发出的命令是敏感,不安全的,或者您只是不需要它使您的历史记录变得混乱,那么最好/最快地只是阻止它首先输入历史记录。确保$HISTCONTROL包含ignorespace

(bash)$ echo $HISTCONTROL
ignoredups:ignorespace

然后使用空格继续执行历史记录中不需要的任何命令:

(bash)$  sensitive-cmd-with --password 82cf7dfe
(bash)$  rm -r... # One-off recursive remove; mustn't be accidentally repeated!

如果您不小心在历史记录中添加了不需要的命令(假设您的bash会话仍处于打开状态),则该命令尚未触及磁盘。要删除历史记录中的上一个命令,请发出:

(bash)$  history -d $((HISTCMD-1))

注意前导空间;此命令要求ignorespace,否则它将自行删除!

如果要删除最后几个命令,请找到最后一个和第一个历史记录编号:

(bash)$  history 5
  598  ok
  599  sensitive
  600  unsafe
  601  doesn\'t-work
  602  otherwise-unwanted

在这种情况下为602和599。然后发出:

(bash)$  for i in {602..599}; do history -d $i; done

(如果没有ignorespace,则为603..599。)

如果您不希望当前会话中的任何历史记录进入磁盘,请使用以下命令退出:

(bash)$ kill -9 $$

到目前为止,这种方法甚至不让敏感的历史记录项写入磁盘以提高安全性,因为从理论上讲,从非易失性介质中删除的数据仍然可以恢复。

但是,如果您希望删除的命令来自上一个会话,则这些命令将已经附加到$HISTFILEon出口上。与上面的命令操纵历史上还是只会追加剩余的项目到$HISTFILE在退出。为了覆盖$HISTFILE与本届会议的观点,整个的历史,现在,问题:

(bash)$  history -w

当然,对于已经在磁盘上的历史记录项目,使用history -d命令然后发出history -w,编辑历史记录的替代方法是$HISTFILE使用文本编辑器进行编辑。


1
“上述命令操纵历史将仍然只追加其余项目到$HISTFILE退出。”其实,这是不完全正确的。似乎只附加了从原始历史记录长度“伸出”的其余新项目。例如,如果我删除5个原始项并添加15个新项,则仅附加最后10个新项,而我希望所有15个新项都将附加。我认为这是一个错误,因为我看不到这是多么理想的功能。
James Haigh 2013年

1
我猜bash记录了原始长度。在会话关闭时,它可能会附加数量大于此值的项目。如果每次删除数量小于或等于此值的项目时此值都会减小,则它将按预期工作。;-)
James Haigh 2013年

15

几种技术:

防止敏感信息存储在历史记录文件中

如果您在命令行中输入了一些密码,然后意识到所有命令都已记录下来,则可以:

  1. 强制退出当前会话而不保存历史记录:

     kill -9 $$

    这将删除所有当前历史记录。

  2. 键入↑ (up arrow)open bash会话,直到显示敏感信息为止,然后使用行编辑键(如Ctrl+)W删除敏感信息,然后 ↓ (down arrow)直到提示新的空行,然后再键入Enter

从历史记录文件中删除敏感信息

如果您意识到已经存储了敏感信息,并且想要删除它,而不是整个历史记录,请执行以下操作:

一个简单的sed命令可以完成这项工作:

sed -e '/SeNsItIvE InFo/d' -i .bash_history

但是,当您键入此内容时,会创建另一个历史记录行,其中包含您要删除的搜索模式(敏感信息)。因此,您可以:

sed -e "/$(head -n1)/d" -i .bash_history

这将head -n1与来自终端的输入一起运行。看来您的终端已挂起(不会出现提示);只需键入要从文件中删除的信息即可。这是一种技巧,使您无需实际在命令行中输入命令即可输入命令(的一部分),从而使其不符合历史记录的条件。然后,sed将使用您键入的文本来搜索.bash_history 和删除包含敏感信息的所有行。注意:如果您的敏感信息模式包含斜杠,则必须使用反斜杠对其进行转义,否则,请更改sed命令以使用此语法来指定模式中不出现的定界符:

sed -e "\|$(head -n1)|d" -i .bash_history

另一种方法是仅删除敏感信息,但保留包含该信息的命令。为此,您可以简单地将敏感信息替换为您选择的替代文本:

sed -e "s/$(head -n1)/Santa Claus/g" -i .bash_history.

从特定树中的任何文件中删除敏感信息

最后,确保不会保留在另一个被遗忘的文件中:

SENSITIVEINFO="$(head -n1)"
find . -type f -print0 | xargs -0 grep -l "$SENSITIVEINFO"

将列出所有相关文件。

find . -type f -print0 |
    xargs -0 grep -l "$SENSITIVEINFO" |
    tr \\n \\0 |
    xargs -0 sed -e "s/$SENSITIVEINFO/Santa Claus/g" -i

将替换根目录为的目录树中所有文件中所有敏感信息.。注意:即使此命令使用xargs -0,它也不会处理名称中带有换行符的文件。


11

通过按↑ (up arrow)直到它出现,找到您要删除的行,然后按Ctrl+ U。那应该删除线。

如果使用该history命令,则可以看到该行已被星号替换。


2
实际上,我相信您必须将光标向上移至该行,按Ctrl + U,然后向上或向下光标至另一行(可能在列表底部为空白)。同样,严格来说,该行还没有被星号代替。而是删除了该命令,并在历史记录编号后附加了*
G-Man

1
使用Ctrl + R(反向增量历史记录搜索),此功能变得更加强大,然后例如[End],Ctrl + U
sehe

4

如果您需要同时删除多行,通常使用以下命令:

history | grep <string> | cut -d ' ' -f 3 | awk '{print "history -d " $1}'

如果需要删除最后一个命令,可以使用:

history -d $((HISTCMD-2))

2
这看起来像是可行的,但history | grep <string>仍显示它声称要删除的所有行...
Brock Hensley

1
删除fisrt后,这将删除错误的历史记录行!!
mivk 2013年

1
但是幸运的是,它仅输出错误的删除命令。以下将显示正确的删除命令:history | grep XYZ | grep -v grep | tac | awk '{print "history -d", $1}'
mivk 2013年

3

如果您需要从历史记录中删除一系列行,则以下bash函数可以为您节省一些时间:

function histdel() {
    [ $# -eq 1 ] && history -d "$1" && history -w
    if [ $# -eq 2 -a "$1" -le "$2" ]; then
        for n in `seq "$2" "$1"`; do
            history -d "$n"
        done
        history -w
    fi
}

函数通常应添加到中$HOME/.bashrc。要立即使用该功能,您将需要正在运行的shell(. $HOME/.bashrc)重新读取该文件。然后从历史记录中删除例如命令200-210:

$ histdel 200 210

(注意:如果您从bash历史记录中删除一系列命令,那么这个问题就是搜索结果中排名最高的一个。因此,尽管以上内容超出了问题的要求,但对某些读者来说还是有用的。)


3
for语句的替代形式:for n in $(seq "$2" "$1")在样式上某些人更喜欢它,如果seq不起作用,请尝试for ((n="$2"; n>="$1"; n--))
斯科特

3
history | sed -i 59d

59是行号。没有比这更甜的东西了:)


3

试试这些

$ history

这将显示历史记录和命令的ID,例如



211 ls
212 javac Welcome.java
213 Java欢迎

采用,

$ history -d 211

211是历史记录的ID。现在使用

$ history



211 javac Welcome.java
212 Java欢迎


2

我知道问和回答这个问题已经有很长时间了,但是我将向您展示清除历史记录文件并同时注销的方法。

我跑: history -w && nano "${HISTFILE}" && history -c && exit

它的作用很简单:

  1. history -w :将缓存的历史记录写入内部 "${HISTFILE}"
  2. nano "${HISTFILE}":允许我编辑"${HISTFILE}"您可以使用sed脚本或任何您想要清洁的内容"${HISTFILE}"
  3. history -c :清除缓存的历史记录,因此不会附加最后一个命令。
  4. exit :注销附加缓存的历史记录...,但是为空;)

执行完该命令后,您将使用干净的历史记录文件注销。登录以查看您的历史记录;)

我希望这会对某人有所帮助。


1

您还可以直接编辑历史文件,例如,nano .bash_history如果您在bash shell中?

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.