
當設定$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
該位置的原因。
如果您碰巧有一個名為 eg 的文件bla:sudo
,那麼*:sudo
也會被此取代。事實並非如此,因為沒有文件與該模式相符。
為了避免這種情況發生,您必須使用單引號以避免任何*
替換:
export HISTIGNORE='ls:ls *:history:history *:sudo *'
更新
順便說一句,HISTIGNORE 沒有什麼特別的,這對於任何變數定義或任何命令都會發生,如果你*
在雙引號內有一個本身,它將被文件列表替換(不以.
!開頭) ) 在當前目錄中(除非當前目錄為空,或僅包含以開頭的文件.
,在這種情況下*
將保持原樣)。