不要将当前bash会话保存到历史记录中

90

我注意到当打开 .bash_history 时,它只包含我上一个会话的记录,当前会话似乎仅在退出时追加。是否有办法防止保存当前会话?即使是崩溃 bash 也可以,如果知道如何做到这一点。我发现可以使用 kill -9 命令结束进程,但如果有更好的方法,我愿意知道。


4
实现这个的一种hack方法是使用kill -9 $$。通过向终端发送SIGKILL信号,它就没有机会写入历史记录文件。 - jordanm
我已经总结了一切,并在此答案中提供了更多的背景信息 https://dev59.com/9Gox5IYBdhLWcg3wr2Po#52208927 - Bruno Bronosky
7个回答

114

1
谢谢,这对于那些在-c选项上清除整个历史记录的Bash版本非常有用。 - dotancohen
这与 history -r 相比的好处是什么呢?因为使用 history -r,你将失去自从登录以来所做的所有操作记录。但是使用这个命令,你不仅会失去之前的记录,还会失去当前会话中即将要执行的所有操作记录。 - Pylinux
@Pylinux 如果你要做一些像在命令行上提供密码这样可疑的事情,那么你可能希望确保如果你在记得清除历史记录之前意外关闭会话,你所要做的事情不会被保存。 - Malvineous
1
迄今为止最常见的用例是:没有注意到终端具有焦点而不是浏览器,意外地在终端中输入密码,现在我必须自己清理 :-) - Pylinux

99

也许比崩溃bash更优雅的方法是使用history -c命令清除当前会话的历史记录。然后,就没有需要保存的内容了(它甚至从历史记录中自动清除)。


13
这将删除历史记录文件中的内容。 - Michael Krelin - hacker
2
对我来说不起作用。也许在某个时候它改变了?我正在使用bash 4.2。 - FatalError
13
在bash 4.3.39版本中,history -c 不仅清除当前会话的历史记录,还清除了bash启动时从历史记录文件开始读取的所有历史记录。如果你要关闭bash,这并不重要。这只是在内存中的历史缓冲区中,它实际上并没有清除历史记录文件(很可能是.bash_history)。 即使您干净地退出bash,它也不会删除历史记录文件。因此,如果您不想退出bash,可以使用 history -r 命令重新读取历史记录文件。遗憾的是,history -cr 不能同时完成这两个操作。 - user1902689
@MichaelKrelin-hacker用“核弹”这个词有点夸张了。我在bash 3.2.57上进行了测试,只有“内存中的历史记录缓冲区”被清除了。这意味着向上箭头将只会响铃。但是您的~/.bash_history不受影响。之后使用的任何命令都将进入您的“内存中的历史记录缓冲区”,如果退出shell,则它们将被追加到您的~/.bash_history中。就像威尔·史密斯在《黑衣人》中一样,而不是在《独立日》中的形象。 - Bruno Bronosky
2
@BrunoBronosky,我没有怀疑的理由,但我认为在编写上述内容之前,我确实在五年前进行了测试。不是我真的记得。也许与其他设置和系统默认值不同或已更改有关... - Michael Krelin - hacker
显示剩余2条评论

30

我知道这是一个旧的帖子。只是想为了完整性而添加:

如果您只想要特定命令不被保存,请检查HISTCONTROL变量是否已设置:HISTCONTROL=ignorebothHISTCONTROL=ignorespace

以前导空格开头的每个命令都不会被记录在历史中。

只是我的两分钱。

来自:man bash

HISTCONTROL
    A colon-separated list of values controlling how commands are saved on the
    history list.  If the list of values includes ignorespace, 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.


那个不错! - Jimmy Koerting
1
ignoreboth 不会输出重复的行,而 ignorespace 会输出重复的行。 - confetti

26

以下是您的 Bash 历史记录工具...

在不保存任何内容的情况下退出 Bash

kill -9 $$

这样做很粗糙而且具有攻击性。但它是结束间谍活动的有趣方式。

从内存中清除历史记录

history -c

这将清除所有历史记录的内存。如果您按上箭头,将什么也不会得到。您的$HISTFILE不受影响。您可以通过以下方式证明这一点...

从磁盘重新加载历史记录

history -r

这会重新读取$HISTFILE并将其附加到内存中的历史记录(如果有的话)。您可以在执行history -c后这样做,以恢复使用Ctrl+R搜索或上箭头查看以前的命令的能力。(您可以这样做,而不是注销然后重新登录)。

注意:如果您没有首先清除历史记录,则此操作仅将内容附加到内存中的当前历史记录。这将使历史记录变得模糊不清,以致于按几次上箭头时,您会认为要隐藏的内容已经消失了。但实际上,它只是被埋藏了起来,并且除非它比您的$HISTSIZE$HISTFILESIZE更深,否则它将被写入磁盘。

执行不包括在历史记录中的命令

参见th3penguinwhisperer的答案,该解决方案是“设置一个选项,使bash不记录以空格为前缀的命令”。我从我的列表中省略了这个内容(以及ignoredupserasedups),因为我认为bash历史记录应该是日志而不是搜索索引。

echo foo bar baz; history -d $(history 1)

这里使用history -d通过序号删除一个历史记录条目。由于只有第一个参数被使用(其他参数会被忽略),我们可以利用history 1的输出(与history | tail -n 1相同)来获取当前历史记录条目的编号。

因为bash单行命令是单独的历史记录条目,所以你可以像这样运行多个命令:

echo foo; echo bar; echo baz; history -d $(history 1)

这也可以工作:

echo foo \
bar \
baz; history -d $(history 1)

即使这样也可以:

for x in foo bar baz; do
echo $x
done; history -d $(history 1)

从历史记录中删除密码(命令等)

如果您只关心删除单个条目,可以创造性地使用上述示例。使用history查找要删除的条目编号,然后按编号进行删除。例如...

$ history
  1  pwd
  2  date
  3  sudovisudo
  4  hunter2
  5  man history
  6  help history
  7  history
$ history -d 4

我希望不用告诉你这个,但以防万一:不要在历史记录中搜索您的密码。如果您真的需要搜索历史记录,请执行history | LESSHISTFILE=/dev/null less,并明确进行/搜索。

如果您真的感到尴尬,想让删除历史记录的内容不被记录,可以将此概念与最后一个结合起来。

history -d 4; history -d $(history 1)

或者也可以消除原始错误...

for n in "$(history 1)" 4 3; do history -d $n; done

请注意需要按照降序循环遍历条目编号,因为每次调用history -d都会将该条目从列表中弹出,并且所有后续条目的编号都会减少1。此外,您需要在子shell周围加上双引号,因为history 1不仅返回编号,还返回命令及其参数,每个内容都会在for循环中单独进行循环。但是这已经变成了一堂 bash 课程,我会停在这里。


1
如果您想执行一个命令但不希望它出现在历史记录中,可以在命令前加一个空格。(此功能可通过HISTCONTROL启用/禁用) - Tianren Liu
@TianrenLiu,这个问题在th3penguinwhisperer的回答中已经解决了,但是既然你提到了它,我也更新了我的答案并链接到他们的答案。 - Bruno Bronosky

16

还有另一种选项,类似于history -c,但不会清除当前会话之前的任何内容。

这是history -r,它从HISTFILE重新加载历史记录,就像你刚登录一样。

我不知道这个命令是否适用于任何早于4.3.11版本的bash,但我认为将其包括在列表中会很有用。

这里有一个示例,展示了这个命令和-c命令之间的区别:

user@host:~$ # I Just logged in
user@host:~$ history | tail -n6 # this shows commands from the previous session, which ends at item 4682 as well as from the current one
 4679  2014-08-23 17:15:29 # Previous session
 4680  2014-08-23 17:15:33 # Still the previous session
 4681  2014-08-23 17:15:37 # note the datetime
 4682  2014-08-23 17:15:44 exit
 4683  2014-08-23 17:17:25 # I Just logged in
 4684  2014-08-23 17:19:54 history | tail -n6 # this shows the last command, and the ones from the previous session
user@host:~$ # This is a secret command, so I need to remove the traces of this session
user@host:~$ history -r
user@host:~$ history | tail -n5 # Note that I went back to item 4682, and there are no traces of history -r command
 6242  2014-08-23 17:15:29 # Previous session
 6243  2014-08-23 17:15:33 # Still the previous session
 6244  2014-08-23 17:15:37 # note the datetime
 6245  2014-08-23 17:15:44 exit
 6246  2014-08-23 17:22:26 history | tail -n5 # Note that I went back to item 4682, and there are no traces of history -r command
user@host:~$ history -c # instead if I issue history -c
user@host:~$ history # everything disappears
 5248  2014-08-23 17:23:13 history # everything disappears
user@host:~$

在Bash 4.3.39上,history -r 将历史文件的内容附加到当前的历史记录列表中。无法确定当您发布回答时是否正在执行此操作... 您的命令之间历史编号跳来跳去,但不会重复。 - user1902689
1
你确定它会附加它们吗?在bash 4.3.11中,数字会向前跳跃,因为计数器没有重置,但实际上它并没有将内容附加到原始内容中。事实上,如果您注销并重新登录,则数字将返回其原始状态。 - Carles Sala

8

应该可以了:

HISTFILE=

取消设置HISTFILE。


谢谢,这个可行,我会在一些过时的服务器上使用它来运行旧版Bash。 - dotancohen
你也可以尝试: unset HISTFILE 如果你不想让本次会话的任何内容出现在历史记录中,这肯定是一个好方法。否则,请参考我上面关于HISTCONTROL的评论。 - th3penguinwhisperer

8
下面的方法对我有效。
 export HISTFILE=/dev/null 

请注意,它前面有一个空格。大多数现代发行版不会将在空格后输入的命令添加到bash历史记录中。这将防止该行出现在您的历史记录中。

这也会使得您现有的历史记录在会话中不可用(例如,Ctrl+R反向搜索对于现有的历史记录将无法使用)。 - Blake Miller
不管是在家里还是在工作中,我都没有任何Ubuntu安装。 使用Ctrl + r仍然有效。它只是不会保存当前终端会话的历史记录。其他什么也没有改变。 - R J

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接