运行多个会话时奇怪的 bash 历史记录行为

运行多个会话时奇怪的 bash 历史记录行为

当我使用多个终端窗口时,命令行历史记录是如何存储的?我知道它存储在,.bash_history但如果我打开新窗口,我看不出使用哪些历史记录的逻辑。它几乎感觉不确定,因为如果我尝试在新窗口中使用向上箭头,我永远不知道我会看到什么命令。

有人能解释一下吗?

有没有办法控制历史记录,以便我可以重复使用特定窗口的历史记录?

答案1

要理解 bash 历史的行为,首先你必须知道以下内容:

  1. 历史文件中有历史记录。
  2. bash 进程的内存中存在历史记录。
  3. 一个 bash 进程内存中的历史记录不与任何其他 bash 进程内存中的历史记录同步。
  4. bash 进程内存中的历史记录不会与文件中的历史记录同步,除非明确要求或在某些特定事件期间(见下文)。

使用默认设置,bash 会话相对于历史记录的生命周期如下:

  1. 在启动过程中,bash 会读取历史文件。历史文件的内容现在位于 bash 进程的内存中。
  2. 在正常使用期间,仅对内存中的历史记录进行操作。
  3. 关机期间,内存中的历史记录将写入历史文件,覆盖历史文件的任何先前内容。

您观察到的看似不确定的行为主要是因为历史记录文件的内容始终是上次关闭的 bash 会话的历史记录,并且 bash 仅在启动期间读取历史记录文件。

阅读bash 手册了解有关启动和关闭过程的更详细说明。

请注意,我所说的默认设置是指 bash 的默认设置。您的发行版可能提供了.bashrc(或/etc/bash.bashrc),这会改变此行为。

通过启用 shell 选项,histappend您可以告诉 bash 追加而不是覆盖历史文件。您可以histappend使用命令启用shopt -s histappend。要始终启用此选项,您必须将命令放入您的.bashrc(或其他初始化文件中)。shoptbash 手册

请注意,启用histappend不会减少看似不确定的行为。这是因为每个 bash 会话在内存中仍然有自己的历史记录。可以拥有大部分同步的 bash 历史记录。有一个指南,教你如何让每个 bash 进程在堆栈溢出上的一个线程

使用内置命令,history您可以明确告诉 bash 将历史记录从文件读取到内存,或将历史记录从内存写入文件。例如:history -r将读取文件的内容并将其附加到内存中的历史记录中(这模仿启动期间的 bash 行为)。history -w将当前历史记录从内存写入文件,覆盖先前的内容(这模仿关闭期间的 bash 行为)。historybash 手册

为了完整起见,这里是修改历史行为的内部变量的列表:

  • HISTFILE:要读取和写入历史记录的文件。
  • HISTCONTROL, HISTIGNORE:防止某些命令保存到历史记录中(仅适用于内存历史记录)
  • HISTFILESIZE,,HISTSIZEHISTTIMEFORMAT与本次讨论无关。

阅读bash 手册了解详情。

答案2

http://www.gnu.org/software/bash/manual/bashref.html#Using-History-Interactively

您可能能够使用其中一个终端来操纵历史文件的写入方式,即在要保存历史记录的终端中执行“history -a”或“history -w”,然后在其他终端中执行“history -r”。取决于您想做什么。

答案3

据我所知,bash 命令在 SSH 会话终止后保存。因此,当会话异常终止(例如,由于网络故障)时,命令不会被保存。我在这里谈论的是 SSH 会话。本地终端可能使用类似的方法。

当同时打开多个会话时,在一个会话中输入的命令不会在另一个会话中显示,只要它们都处于活动状态。但是,当您终止会话并重新打开它时,您将看到这些命令。

相关内容