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