问题陈述
我一直在关注大量使用 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 来解决这个问题。
希望这能对其他人有所帮助。