隐身模式终端?

我经常使用终端,并且有时候运行的命令不是我不想让别人看到的东西,而是一些如果我不小心按上箭头并意外执行的命令会引起很多麻烦。
所以我想知道是否有一种终端的“隐身模式”,允许我在执行特定命令后停止记录我的历史记录,然后只有在我再次执行开始记录历史命令并退出“隐身模式”,或者简单地重新启动终端后才开始记录?
因为我发现自己后来要去删除我的.bash_history中的内容,如果我一开始就能停止记录,或者至少让它尝试将记录保存在一个不允许的位置,最后不会记录下来,那将会更容易。

6嗯,大概你很担心别人会读到你的浏览历史吧? - Sparhawk
6@Sparhawk:这部分是因为我不想在未来向上箭头时意外执行可能致命的维护命令! :D - user364819
19只是补充一下,你不必为自己辩解:“这些并不是我不希望别人看到的东西”。对我来说,这也是一个完全合理的理由。(尤其是在这个时代,每个人都试图让你看起来有“隐瞒的东西”而感到有罪的时候) - ereOn
2如果你打开两个标签页,在第一个标签页上做一些操作,然后在第二个标签页上做一些操作,最后在第一个标签页关闭之前先关闭第二个标签页,那么只有第一个标签页的历史记录似乎会被写入到.bash_history文件中。(Ubuntu 15.04破坏了终端,幸运的是这是一个活动的USB。) - Hitechcomputergeek
1请参考serverfault上的这个问题。 - Luc M
1这对于需要在命令行界面上输入密码或某些安全凭据的命令或程序也会很方便,这些凭据将被存储在你的 .bash_history 文件中。 - jwbensley
10个回答

在不将其记录在历史中的情况下运行命令:

只需在命令之前加一个空格。Bash会忽略带有前置空格的命令:

示例:空格echo "一些秘密文本"

注意:这仅在HISTCONTROL变量设置为ignorespaceignoreboth时才起作用。


暂时禁用历史记录:

  • 运行 Spaceset +o historySpaceshopt -uo history 来禁用历史记录。
  • 运行 set -o historyshopt -so history 来重新启用它。

禁用当前会话的历史记录(不会记住该会话中的任何命令):
unset HISTFILE

注意:只要你不关闭终端,你就可以通过按下上箭头键来查看命令。
从历史记录中删除一个命令:
运行 Spacehistory | grep "你的秘密命令的一部分" 它将显示以以下格式列出的先前运行的命令列表:
user@host:~$  history | grep pkill
  302  pkill $$
  467  pkill gone-cal
  468  pkill actionaz
  500  pkill chrome
  550  pkill super

选择命令左侧的条目编号。你可以使用 Ctrl+Shift+C 复制它。
运行 Spacehistory -d <number>,其中 <number> 是要删除的条目编号。
你可以使用 Ctrl+Shift+V 粘贴该编号。

其他有趣的答案:


8如果你使用history -d来删除一行,这将删除该行的内容,但你无法删除运行history -d的事实(除非你在运行history -d之前先使用set +o history)。 - AJFaraday
1这只是让我想起了超禁令的逻辑,仅此而已 ;) - AJFaraday
@AJFaraday:抱歉,我不太理解你的评论,英语不是我的母语。你能解释一下吗? - 0x2b3bfa0
4(OT)禁令是一份法律文件,可以阻止人们发布某些内容。而超级禁令则进一步阻止他们公开被拒绝发布该信息的事实。一些逻辑上的争辩提问能否发布他们被拒绝发布某些信息的事实。这样就形成了一个循环论证的情况。 - AJFaraday
@AJFaraday: ;-) 现在我明白了,谢谢。是的,你是正确的。哈哈。 - 0x2b3bfa0
@Helio 我对你的回答进行了一些相当大胆的格式更改。我个人认为这样做可以使阅读更加容易,也更容易让人理解你的意思(对我来说,Space+Command语法很令人困惑)。如果你不同意,随时可以进行部分/完全回滚。 - Tim
@Tim:我部分同意你的更改... 我认为Space,作为一个不可打印字符,最好用一些“实体”的东西来表示,而且尤其是在行的开头... 我同意history的示例输出。我部分同意慢速复制/粘贴方法。我会部分还原你的更改。如果你有其他意见,可以随时撤销我的还原 ;-) - 0x2b3bfa0
1@Helio 我认为让用户知道“正确”的复制方式更好,特别是如果他们意外选择了一些文本。我不确定如何添加空格,也许可以更明确地说明有空格存在?对我来说,[空格]看起来有点笨拙... - Tim
如何澄清一个空白字符? - 0x2b3bfa0
3unset HISTFILE 这种方法也可以对尚未写入 .bash_history 的所有命令进行追溯操作。 - kasperd
@kasperd:谢谢!如果我的编辑不够清楚,请随意修改我的回答。 - 0x2b3bfa0
提醒应该是“记住” - A. Donda
@A.Donda,抱歉,英语不是我的母语。 - 0x2b3bfa0

您可以通过在工作后添加命令history -cw来简单删除一个特定终端会话的历史记录。
在执行此命令之前,请不要关闭终端。

这样做不会删除所有的历史记录吗? - 0x2b3bfa0
6这将只会删除该特定终端会话的历史记录。 - Moithil Biswas
请注意。这个命令清除了我的.zsh_history记录。 - Chris Jeong

shopt -uo history是最好的选择。

清除HISTFILE(等等)变量不会阻止记录你的Up历史,只是不会将其推送到磁盘。这对你来说可能是好事,也可能不是,但考虑到你提到了它,我想你希望有更好的解决办法。改变shopt历史设置可以阻止整个历史机制触发。

你可以使用shopt -so history重新开启记录功能(-s-u分别是设置和取消设置)。

请注意,命令本身可能会被记录,因此在清除变量之前,在命令前加一个空格以阻止其被添加到历史记录中。


另一种在不记录到历史文件的情况下终止当前shell的方法是执行以下操作:
kill -9 $$

这会导致bash(可能也包括其他shell)向自身发送SIGKILL信号,立即终止并阻止其向磁盘写入任何内容。

9也就是说,你可以直接开干了:) 这样做的好处是,在写命令之前,你不需要记住要做任何事情。 - Guido
4我使用带有增量历史记录写入的zsh,所以我怀疑这在我的情况下是否有效。 - Wayne Werner

为了临时禁用当前会话的命令历史记录,您可以暂时取消设置HISTFILE环境变量。
unset HISTFILE

在会话仍然有效的情况下,您可以像往常一样访问历史记录,但不会保存到磁盘上。
在同一会话中进行撤销操作(所有更改将被记录)。
HISTFILE=$HOME/.bash_history

1在当前会话中,是否有一种简单的方法来反转这个操作,并使其继续进行? - user364819
@ParanoidPanda 我在当前会话中添加了一个还原命令。 - Bruni
1@ParanoidPanda:为什么你需要在当前会话中再次设置HISTFILE的命令?即使在运行秘密命令后撤销更改,它们在退出时仍会被存储到历史记录中。 - 0x2b3bfa0
@Helio:哦,不好意思,我是指一个命令,它会重新开始录制,但不保存我不想保存的命令。 - user364819
然后unset HISTFILE或者HISTFILE=$HOME/.bash_history都不会起作用。请查看Oli的回答或者我的回答。 - 0x2b3bfa0
1@ParanoidPanda,Helio 在这件事上似乎是对的,因为历史记录在退出时会保存。我之前没有考虑到这一点。 - Bruni

你可以在当前的shell会话中修改历史命令行。如果你通过历史记录回溯(例如使用上箭头Ctrl+P)并且修改一行而不执行它,只有修改后的版本会被保存。你可以按照任何方式进行修改;好的选择包括使用Ctrl+U完全清空该行,或者使用Esc#在开头添加一个#注释字符。
要离开一行而不执行它,请记住不要按下回车键(Enter)。我通常是通过Esc>返回到历史记录中最新的一行。
(在大多数终端中,你可以按住Alt键然后按下>来代替Esc后跟>;对于上面提到的Esc#建议也是一样。) 注意:你无法永久修改之前会话中的条目。这些更改不会应用到会话结束时的HISTFILE文件中。

你还可以将.bash_history设为只读。我会先清空文件,然后执行以下操作:
 chattr +i .bash_history

你可以在一个screen会话中执行敏感命令,然后在完成后销毁该会话。
或者,你可以保持该screen会话处于活动但分离状态,只有在实际需要时才访问它,以便能够使用向上箭头来输入其他危险命令。

你也可以使用终端复用器,如tmux、screen。因此,在tmux或screen下,历史记录不会被保存。

个人而言,我使用的是mksh,而这个shell默认没有历史文件。这意味着你可以启动其他的shell,比如mksh或者dash(顺便说一下,默认就有),来运行你不想让用户看到的命令,并在完成后退出。bash的历史记录只会记录你启动了其他的shell,仅此而已。