Bash
為什麼“*”在不同命令中的工作方式不同?
例如,in
rm -r abc*
"*"
表示任何字元串。但是,如果我們使用它touch abc* abcd* abcde*
(並且我們在目錄中沒有任何以 abc 或 abcd 或 abcde 開頭的文件)"*"
意味著只是一個符號,並且abc* abcd* abcde*
將創建文件。如果在那之後我們將使用touch -m ab*
文件的修改時間abc* abcd* abcde*
將被更改。為什麼在某些情況下
"*"
意味著任何字元串,而在某些情況下它只是一個符號?電腦如何知道何時改變它的含義?
當
abc*
在 shell 中使用不帶引號的模式時,shell 將嘗試將其與可用的文件名匹配(這稱為“文件名生成”,但通常稱為“萬用字元”)。如果它無法匹配任何文件名,大多數sh
類似的 shell 將保持模式未擴展並按原樣將其傳遞給實用程序。例子:
$ touch xyz $ touch abc* $ tree . |-- abc* `-- xyz 0 directory, 2 files
$ touch xyz* $ tree . |-- abc* `-- xyz 0 directory, 2 files
該
touch xyz*
命令沒有創建名為 的文件xyz*
,因為文件名xyz
與模式匹配。因此使用文件名呼叫該touch
實用程序xyz
。在shell 中,如果 shell glob 不匹配任何內容
bash
,設置failglob
shell 選項將使 shell 抱怨:shopt -s failglob
$ shopt -s failglob $ touch 123* bash: no match: 123*
zsh
預設情況下, shell中打開等效選項。如果模式與文件名不匹配,在(或)中設置
nullglob
shell 選項會使模式消失:bash``NULL_GLOB``zsh
$ shopt -s nullglob $ touch fo* usage: touch [-acm] [-d ccyy-mm-ddTHH:MM:SS[.frac][Z]] [-r file] [-t [[cc]yy]mmddHHMM[.SS]] file ...
(我們得到一個錯誤,
touch
因為它是在沒有任何參數的情況下呼叫的)為了保證模式被用作字元串(原樣),而不是用於萬用字元,您應該引用它:
$ touch "file*" $ touch "file**" $ touch "file***" $ tree . |-- file* |-- file** `-- file*** 0 directory, 3 files
在這個例子中不引用文件名只會給你一個名為
file*
的文件(如果目錄最初是空的),因為file**
andfile***
模式匹配那個file*
名字。