几天前,我让一个终端选项卡在执行ssh
,而另一个在本地执行大量工作。然后我重新启动了机器(在带有 Mavericks 的 Mac 上)。
当我再次运行终端时,我发现第二个选项卡的所有命令历史记录都不存在。只有ssh
命令。
所以然后我搜索了如何以某种方式“合并”历史记录,发现我们需要shopt -s histappend
在我们的~/.bashrc
文件中执行 a 以便历史记录会附加,而不是“覆盖”——我们不希望一组历史记录覆盖另一组历史记录放;我们想要追加。
但是,当我转到 OS X Yosemite 盒子并使用 时shopt
,我看到它histappend
已关闭,但是当我打开两个选项卡,一个在执行echo abc
,另一个在执行echo def
,然后退出它们时,我再次重新打开终端并发出history
命令,并看到了echo abc
和echo def
命令。
然后我在 VirtualBox 上运行 Ubuntu 2014-10 并做了类似的事情,并且仍然看到记录的历史记录(我首先shopt -u histappend
在两个 Bash 中运行以先将选项设置为关闭)。
那么到底是什么机制在这样做呢?那么histappend
就没有意义了,如果设置为开或关都没有关系的话?
我还注释掉了shopt -s histappend
我的.bashrc
终端并重新启动并再次尝试,并看到两个选项卡能够组合的历史记录......所以这确实是奇怪的行为,是什么原因导致的?
答案1
@戴大卫关于这个 bash-help 线程的说法是正确的。
这里bash
是C中的相关代码。
if (history_lines_this_session <= where_history () || force_append_history)
{
result = append_history (history_lines_this_session, hf);
history_lines_in_file += history_lines_this_session;
}
else
{
result = write_history (hf);
history_lines_in_file = history_lines_this_session;
}
shopt -s histappend
设置force_append_history
为非零 ( true
)。
history_lines_this_session
bash
是您在此交互式会话中键入的命令数。当你第一次启动 bash 时,它是 0。每执行Enter一个保存到历史记录的命令,它就会增加 1。
where_history()
是内存中历史记录列表的索引,从索引 0 开始。它指向要写入历史记录的下一个索引。例如,当您有 0 条历史记录时,它将是索引 0。当您有 6 行历史记录时,它将是索引 6。
当你第一次开始bash
并且你有历史记录时HISTFILE
,where_history()
增加但会受到限制<= HISTSIZE
。所以where_history()
有最大值HISTSIZE
.
读取后HISTFILE
,where_history()
会增加,但history_lines_this_session
仍为 0。当您Enter HISTSIZE + 1
执行命令数 时,history_lines_this_session == HISTSIZE + 1
和where_history() == HISTSIZE
(因为它有最大值)。此时,如果关闭,(history_lines_this_session <= where_history()) == false
历史记录将被覆盖。histappend
您可以自己测试一下bash
。如果histappend
关闭,一旦运行HISTSIZE + 1
命令数量history_lines_this_session
将超过where_history()
1 并且HISTFILE
将被覆盖。您必须确保其他命令不会干扰您的历史记录才能使测试正常进行(发生在 macOS 上)。使用以下命令关闭可能会扰乱历史记录的命令:
trap - EXIT
PROMPT_COMMAND=
SHELL_SESSION_HISTORY=0 # for macOS only
答案2
我相信histappend
这是为一终端。
在新终端中尝试以下操作:
shopt -s histappend
export HISTSIZE=1
export HISTFILESIZE=500
然后关闭终端。然后,您将看到您的历史文件如何包含它已经包含的最后 499 个最后命令以及export HISTFILESIZE=50
您刚刚键入的“”。您的历史记录已被追加,然后被截断为 500。
现在在另一个新终端中尝试此操作:
shopt -u histappend
export HISTIZE=1
export HISTFILESIZE=500
再次关闭终端。您将看到现在您的终端只有一个命令“ export HISTFILESIZE=500
”。
诀窍是,如果没有histappend
,历史文件将被终端历史记录中当前的内容(一个命令)覆盖。
你不会注意到它的行为 if HISTFILE
=HISTFILESIZE
但我相信它与在多个终端上工作无关,这必须由其他东西管理......