为什么这个删除部分命令历史记录的脚本无法在我的电脑上运行?

为什么这个删除部分命令历史记录的脚本无法在我的电脑上运行?

该脚本可以在这里找到:https://stackoverflow.com/questions/14750650/how-to-delete-history-of-last-10-commands-in-shell

为了方便起见,这里是:

for x in `seq $1 $2`
do
  history -d $1
done

我把它放在我的包含目录(我已将其添加到 PATH 中)中,在那里我运行我编写的许多其他脚本并且运行良好。

这不会产生从我的历史记录中删除行的预期结果,事实上它根本没有做任何事情。

知道为什么 history 命令不起作用吗?我想知道这是否与目录有关。

附加信息:

我尝试了代码并尝试了不同的变体。如果我在命令echo前面加上一个history并运行它,我会得到以下输出:

cgravel@scspc578:~$ idelhistory 300 305
history -d 300
history -d 301
history -d 302
history -d 303
history -d 304
history -d 305
cgravel@scspc578:~$ 

所以,对我来说,它似乎应该完美地工作。我不明白为什么。此脚本正在从 /$HOME/Scripts/ 运行,并且已包含在 PATH 中。我也尝试使用 sudo 运行它,但没有任何变化。

答案1

一句话概括:它不起作用,因为你没有正确调用它。

首先,由于你的脚本不是以#!/bin/bash,它实际上不是 bash 脚本。它由哪个 shell 执行取决于你如何调用它。当你从 bash 命令行调用它时,bash叉子创建一个自己的新实例(无论如何,这必须发生才能执行任何外部命令),并且这个新实例执行脚本。因此,脚本使用与父 shell 相同的设置(包括迄今为止的历史记录)执行。它使用不同的设置执行选项;特别是,脚本中的命令的历史记录跟踪是关闭的(这很适合您,因为否则它会添加到您想要修改的历史记录中)。

执行脚本的 bash 实例是否具有HISTFILE多变的设置取决于它是否在父级中导出(这有点奇怪)。如果它没有导出,因此在子级中设置,那么子脚本在结束时不会保存修改的历史记录。

如果HISTFILE导出,则子脚本将修改您的历史文件。但是,除非您已将交互式 shell 配置为每条命令执行后重新加载历史记录,修改的历史记录将只有新启动的 bash 实例才会拾取。

如果要运行影响当前 shell 实例的 shell 代码片段,您必须在当前 shell 实例中运行该 shell,而不是将其作为子进程运行。如果你想做其他影响 shell 进程本身的事情,比如更改目录、设置变量等,你也会遇到类似的问题。使用.(“点”)或source内置在当前 shell 进程中运行脚本。

. idelhistory 300 365

或者,您可以将其定义为您的 中的一个函数.bashrc

答案2

编辑:似乎在运行此脚本的某些机器上仍然存在一些问题。另一种(也许是最好的)方法是不尝试使用 shell 内置命令,而是直接修改 $HISTFILE

#!/bin/bash
HISTFILE=~/.bash_history # Or just let the shell decide
for x in `seq $1 $2`
do
  sed "\'$1d\'" $HISTFILE
done

原始答案:

问题似乎在于非交互地运行 bash 脚本......

这个关于 Unix 和 Linux 的帖子似乎涵盖了一种让您的脚本正常工作的解决方法:

#!/bin/bash
HISTFILE=~/.bash_history   # Or wherever you bash history file lives
set -o history             # enable history
for x in `seq $1 $2`
do
  history -d $1
done

相关内容