在交互式会话中从子 shell 内部修改 bash 历史记录

Wei*_*hou 1 bash history

我执行了

history > before; (history -d $n); history > after
Run Code Online (Sandbox Code Playgroud)

其中$n是与执行此行之前我在同一交互式会话中键入的最后一个命令相对应的数字,

结果是标记的行$n没有从历史记录中删除。如果我删除括号以便history -d在当前 shell 中运行,它将按记录工作。

如何理解这种行为?是不是所有操纵历史的脚本都需要source编写?

hma*_*ica 6

每个 shell 进程对于命令行历史记录都有自己的想法。当交互式 shell 退出时,它将写入其记住的历史记录,~/.bash_history以便下一个 shell 拾取,但这就是 shell 进程之间的合作范围。

在您的命令中,会使()shell 分叉自身的副本来运行history -d命令。子进程从父进程内部状态的副本开始,因此它知道历史记录,并且能够对其副本进行更改。

但是,当子 shell 退出时,其历史记录副本(刚刚重写)将与其内部状态的其余部分一起被丢弃。子shell知道它是一个子shell,所以它甚至懒得写~/.bash_history.


没有来源的脚本通常根本无法操作历史记录,因为它是由一个新的非交互式shell 解释的,而该 shell 在启动时甚至不读取~/.bash_history

可以通过在命令行上指定 shell 来使其表现得像交互式 shell:

#!/bin/bash -i
echo something
Run Code Online (Sandbox Code Playgroud)

运行此脚本的 shell 会将其命令(包括 shebang 行和 )附加echo something~/.bash_history它在磁盘上找到的命令。当然,这不会影响您调用脚本的 shell 进程的内存历史记录副本,并且当它退出时,脚本所做的更改~/.bash_history无论如何都会丢失。