Bash

為什麼“*”在不同命令中的工作方式不同?

  • October 1, 2019

例如,inrm -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,設置failglobshell 選項將使 shell 抱怨:shopt -s failglob

$ shopt -s failglob
$ touch 123*
bash: no match: 123*

zsh預設情況下, shell中打開等效選項。

如果模式與文件名不匹配,在(或)中設置nullglobshell 選項會使模式消失: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*名字。

引用自:https://unix.stackexchange.com/questions/544534