我执行了
history > before; (history -d $n); history > after
其中$n
是与执行此行之前我在同一交互式会话中键入的最后一个命令相对应的数字,
结果是标记的行$n
没有从历史记录中删除。如果我删除括号以便history -d
在当前 shell 中运行,它将按记录工作。
如何理解这种行为?是不是所有操纵历史的脚本都需要source
编写?
答案1
每个 shell 进程对于命令行历史记录都有自己的想法。当交互式 shell 退出时,它将写入其记住的历史记录,以便~/.bash_history
下一个 shell 拾取,但这就是 shell 进程之间的合作范围。
在您的命令中,()
会使 shell 分叉自身的副本来运行history -d
命令。子进程从父进程内部状态的副本开始,因此它知道历史记录,并且能够进行更改它是它的副本。
但是,当子 shell 退出时,其历史记录副本(刚刚重写)将与其内部状态的其余部分一起被丢弃。子shell知道它是一个子shell,所以它甚至懒得写~/.bash_history
.
没有来源的脚本通常根本无法操纵历史,因为它是由新鲜的脚本解释的。非交互式shell 在启动时甚至不读取~/.bash_history
。
你能通过在命令行上指定,使 shell 的行为类似于交互式 shell:
#!/bin/bash -i
echo something
运行此脚本的 shell 会将其命令(包括 shebang 行和echo something
)附加到~/.bash_history
它在磁盘上找到的命令。但这当然不会影响您所创建的 shell 进程的内存历史记录副本调用脚本从,并且当它退出时,脚本所做的更改~/.bash_history
无论如何都会丢失。