Bash 的 Bug?? 当 `$HISTIGNORE` 的设置以 `SP`+`*` 或 `SP`+`?*` 结尾时

Bash 的 Bug?? 当 `$HISTIGNORE` 的设置以 `SP`+`*` 或 `SP`+`?*` 结尾时

当设置$HISTIGNORESP+*SP+结尾时?*,当前文件夹中的文件列表将与其值连接。

无论extglob是否设置。

NG 示例,(当前文件夹只有一个文件“do_music.sh”):

$ export HISTIGNORE="ls:ls *:history:history *:sudo *"
$ echo $HISTIGNORE
ls:ls *:history:history *:sudo do_music.sh
$

确定示例:

$ export HISTIGNORE="ls:ls *:history *:sudo *:history"
$ echo $HISTIGNORE
ls:ls *:history *:sudo *:history
$

答案1

更新 2

根据我最初的回答,您需要使用单引号来*保持原样。如果这样做,变量HISTIGNORE将只包含*而不是扩展。当您 时echo,您会看到扩展正在发生,因为 shell$HISTIGNORE用 a替换*,然后用文件列表替换。

您可以通过env | grep HISTIGNORE在两种情况下运行来验证。在"-case 中,您将看到do_music.sh,在'-case 中,您将看到*

另外,您可以尝试export HISTIGNORE在一个目录中运行该行,然后echo在另一个目录中运行该行,您将看到差异,具体取决于您使用'还是"

(我删除了上面的部分,因为它被证明是错误的,毕竟单引号和双引号都应该适用于你的情况,因为*在双引号内也没有被替换)。

更新 3

您得到此行为的原因echo是由于 bash 中的替换顺序。根据手册:

       The  order of expansions is: brace expansion; tilde expansion, parameter and vari‐
       able expansion, arithmetic expansion, and command substitution (done in a left-to-
       right fashion); word splitting; and pathname expansion.

首先发生參數/變數扩展($HISTIGNORE对 的更改*),之后发生路径名扩展(*文件列表中的更改)。

以下是原始答案

当你执行第一行时:

export HISTIGNORE="ls:ls *:history:history *:sudo *"

shell 已经将最后一个文件扩展*到目录中的文件列表,这就是您到达do_music.sh该位置的原因。

如果你碰巧有一个名为 的文件bla:sudo,那么*:sudo也会被这个替换。但事实并非如此,因为没有文件与该模式匹配。

为了避免这种情况发生,您必须使用单引号来避免任何*替换:

export HISTIGNORE='ls:ls *:history:history *:sudo *'

更新

顺便说一句,HISTIGNORE 没有什么特别之处,这会发生在任何变量定义或任何命令中,如果你*在双引号内的某处有一个,它将被当前目录中的文件列表(不以.!开头)替换(除非当前目录为空,或者仅包含以!开头的文件.,在这种情况下*将保持原样)。

相关内容