bash:除非 HISTFILE 已经有文本,否则 history -a 不会写入

bash:除非 HISTFILE 已经有文本,否则 history -a 不会写入

问题陈述

我一直在关注大量使用 bash 历史进行创造性操作的例子,例如:

# simplified example
PROMPT_COMMAND='history -a; history -c; history -r'

...但它似乎时断时续地工作。如果历史文件已经存在,并且包含以前的历史记录,那么一切都很好。

其他相关信息

  • bash 版本:3.2.51、4.1.2 和 4.2.45
    • 4.2.x 似乎没有这个问题,但它不是默认安装
  • 操作系统:Linux 和 Solaris
  • 主目录已挂载 NFS

诊断步骤

我摆脱了我的.bashrc并将我的设置.bash_profile为:

HISTFILE=$HOME/.bash_history.test

然后我将启动一个登录 shell(例如,通过 ssh 连接到另一台机器)并执行以下操作:

~ cat .bash_history.test
cat: .bash_history.test: No such file or directory
~ history
    1  cat .bash_history.test
    2  history
~ history -a
~ !-3
cat .bash_history.test
cat: .bash_history.test: No such file or directory

history -a在下列情况下,历史文件不会被附加:

  • 该文件尚不存在
  • 文件为空或仅包含换行符;即使有空格也能正常工作

...然而,当 shell 退出时创建它。此后,history -a按预期工作……除了PROMPT_COMMAND="history -a; history -c; history -r"。当我设置了该设置时,即使退出 shell 也不会创建历史文件(除非我exec bash先运行)。

然后我尝试使用非标准安装的 bash (4.2.x),但问题没有出现。

答案1

此邮件列表主题似乎解释了这些问题;引用第二条消息:

bashhist.c:maybe_append_history() 中的当前代码(已存在至少 15 年)似乎无法处理当前会话中的历史行数等于历史列表条目数的情况。也就是说,如果代码认为在 shell 启动时没有从历史文件中读取任何行,它将不会附加新行。这似乎是错误的,我已附加了一个修复该问题的补丁。但是,代码以当前形式存在了很长时间,我想知道是否还有其他原因。

(Chet Ramey,GNU bash 邮件列表)

此外,变更日志4.2 版有以下文字:

+                  8/13
+                  ----
+bashhist.c
+   - in maybe_append_history, change check for history_lines_this_session
+     so that we append the lines to the file if it's equal to the value
+     returned by where_history().  This means that without this change,
+     the history won't be appended if all the lines in the history list
+     were added in the current session since the last time the history
+     file was read or written.  Fixes bug reported by Bruce Korb
+     <[email protected]>

(git.savannah.gnu.org, bash git repo)

显然,我们需要安装较新版本的 bash 来解决这个问题。

希望这能对其他人有所帮助。

相关内容