Weijun Zhou Asked: 2019-04-22 03:18:14 +0800 CST2019-04-22 03:18:14 +0800 CST 2019-04-22 03:18:14 +0800 CST 在交互式会话中从子外壳内部修改 bash 历史记录 772 我执行了 history > before; (history -d $n); history > after 其中$n是对应于我在执行此行之前在同一交互式会话中键入的最后一个命令的数字, 结果是标记的行$n没有从历史记录中删除。如果我删除括号以便history -d在当前 shell 中运行,它会按记录工作。 如何理解这种行为?是否所有操纵历史的脚本都需要sourced? bash history 1 个回答 Voted Best Answer hmakholm left over Monica 2019-04-22T06:47:48+08:002019-04-22T06:47:48+08:00 每个 shell 进程对命令行历史记录都有自己的想法。当一个交互式 shell 退出时,它会将其记住的历史记录写入~/.bash_history下一个 shell,但这是 shell 进程之间合作的程度。 在您的命令中,()使 shell fork 自身的副本以运行history -d命令。子进程从父进程内部状态的副本开始,因此它知道历史,并能够对其副本进行更改。 但是,当子shell 退出时,它的历史副本(刚刚被重写)连同其内部状态的其余部分一起被丢弃)。subshell 知道它是一个 subshell,所以它甚至懒得写~/.bash_history. 没有来源的脚本通常根本无法操纵历史,因为它是由一个新的非交互式~/.bash_historyshell 解释的,它甚至在启动时都不会读取。 您可以通过在命令行中指定 shell 来让 shell 表现得像交互式 shell: #!/bin/bash -i echo something 运行此脚本的 shell 会将其命令(包括 shebang 行和echo something)附加到~/.bash_history它在磁盘上找到的命令。但这当然不会影响您从中调用脚本的 shell 进程的内存历史副本,并且当它退出时,脚本所做的更改~/.bash_history无论如何都会丢失。
每个 shell 进程对命令行历史记录都有自己的想法。当一个交互式 shell 退出时,它会将其记住的历史记录写入
~/.bash_history
下一个 shell,但这是 shell 进程之间合作的程度。在您的命令中,
()
使 shell fork 自身的副本以运行history -d
命令。子进程从父进程内部状态的副本开始,因此它知道历史,并能够对其副本进行更改。但是,当子shell 退出时,它的历史副本(刚刚被重写)连同其内部状态的其余部分一起被丢弃)。subshell 知道它是一个 subshell,所以它甚至懒得写
~/.bash_history
.没有来源的脚本通常根本无法操纵历史,因为它是由一个新的非交互式
~/.bash_history
shell 解释的,它甚至在启动时都不会读取。您可以通过在命令行中指定 shell 来让 shell 表现得像交互式 shell:
运行此脚本的 shell 会将其命令(包括 shebang 行和
echo something
)附加到~/.bash_history
它在磁盘上找到的命令。但这当然不会影响您从中调用脚本的 shell 进程的内存历史副本,并且当它退出时,脚本所做的更改~/.bash_history
无论如何都会丢失。