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


15

使用多个终端窗口时如何存储命令行历史记录?我知道它存储在其中,.bash_history但是如果我打开新窗口,则看不到使用什么历史记录的逻辑。从某种意义上来说,几乎感觉不到是不确定的,如果我尝试在新窗口中使用向上箭头,我将永远不知道会看到什么命令。

有人可以解释吗?

有没有一种方法可以控制历史记录,以便可以从特定窗口重用历史记录?

Answers:


14

要首先了解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将读取文件的内容并将其附加到内存中的历史记录中。history -w会将当前历史记录从内存写入文件,覆盖以前的内容。这基本上是关机期间发生的情况。historybash手册中阅读有关命令的更多信息

为了完整起见,以下是修改历史记录行为的内部变量的列表:

  • HISTFILE:要读取和写入历史记录的文件。
  • HISTFILESIZE:历史文件的最大行数。
  • HISTSIZE:内存中历史记录的最大行数。
  • HISTCONTROLHISTIGNOREHISTTIMEFORMAT:对于这个讨论不相关的。阅读bash手册以了解详细信息。

很好的解释。您提到了关机,但是如何终止终端会话呢?可以通过注销或UI或通过其他一些方式(如断开网络连接)杀死会话。如果替换了整个历史记录文件,并且您有多个会话,是否表示历史记录文件中将使用上次关闭的历史记录?这可以解释非确定性行为。
Alex Gitelman

生命周期点(3)不正确。似乎只有第一个bash会话才会写入历史文件。测试:按顺序a,b打开2个会话。在b中 “打招呼” 。然后在b中退出。然后打开一个新会话c。此会话在其历史记录中不会回声。
user606723 2011年

@AlexGitelman:如果bash进程被杀死,则它将没有机会覆盖历史文件。是的,上一个关闭的会话的历史记录将在历史记录文件中。
lesmana 2011年

@ user606723:点3是正确的。阅读bash手册。使用最小.bashrc文件再次进行实验。请注意,您的发行版可能已更改了中的某些设置/etc/bash.bashrc。专门检查shell选项histappend
lesmana


0

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

当同时打开多个会话时,在一个会话上键入的命令都处于活动状态,而在另一会话上则看不到它们。但是,当您终止会话重新打开它时,您将看到这些命令。


这不是我所经历的行为。我可以通过在打开ssh会话,执行命令和正常退出的地方进行快速测试来确认这一点。在这种情况下,我有另一个以前处于活动状态的ssh会话。在此先前存在的bash会话中,我检查.bash_history并没有发现任何记录。我发现运行的第一个bash会话可能是唯一一个最终记录到.bash_history的会话。
user606723 2011年

终止会话不会影响当前正在运行的会话,但是会影响新的会话!
哈立德

如果不是通过SSH而是通过UI关闭的Gnome终端窗口怎么办?
Alex Gitelman

需要验证。目前,我无法访问Gnome终端!
哈立德

经过测试的@Khaled不会影响新的会话。(无论如何,我还是在之前检查过.bash_history,这是bash获取新会话的命令历史记录的地方,我知道那是行不通的,但是无论如何我都对你很反感。)
user606723 2011年
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.