为什么“*”在不同命令中的作用不同?

Gid*_*eon 0 shell bash command touch

例如,inrm -r abc* "*"表示任何字符串。但是,如果我们使用它touch abc* abcd* abcde*(并且目录中没有任何以 abc 或 abcd 或 abcde 开头的文件)"*"意味着只是一个符号,并且abc* abcd* abcde*将创建文件。如果在那之后我们将使用touch -m ab*的文件的修改时间abc* abcd* abcde*将会改变。

为什么在某些情况下"*"意味着任何字符串,而在某些情况下它只是一个符号?计算机如何知道何时更改其含义?

Kus*_*nda 7

abc*在 shell 中使用不带引号的模式时,shell 将尝试将其与可用文件名进行匹配(这称为“文件名生成”,但通常称为“globbing”)。如果它无法匹配任何文件名,大多数sh类似 shell 将不展开模式并将其按原样传递给实用程序。

例子:

$ touch xyz
$ touch abc*
$ tree
.
|-- abc*
`-- xyz

0 directory, 2 files
Run Code Online (Sandbox Code Playgroud)
$ touch xyz*
$ tree
.
|-- abc*
`-- xyz

0 directory, 2 files
Run Code Online (Sandbox Code Playgroud)

touch xyz*命令并不会创建一个名为xyz*,因为文件名xyz匹配的模式。touch因此使用xyz文件名调用该实用程序。

bashshell 中,如果 shell glob 不匹配任何内容,则将failglobshell 选项设置为withshopt -s failglob将使 shell 抱怨:

$ shopt -s failglob
$ touch 123*
bash: no match: 123*
Run Code Online (Sandbox Code Playgroud)

默认情况下,zshshell 中的等效选项处于打开状态。

如果nullglobbash(或NULL_GLOBin zsh) 中设置shell 选项将使模式消失,如果它与文件名不匹配:

$ shopt -s nullglob
$ touch fo*
usage: touch [-acm] [-d ccyy-mm-ddTHH:MM:SS[.frac][Z]] [-r file]
             [-t [[cc]yy]mmddHHMM[.SS]] file ...
Run Code Online (Sandbox Code Playgroud)

(我们得到一个错误,touch因为它是在没有任何参数的情况下调用的)

为了保证模式被用作字符串(按原样),而不是用于通配符,您应该引用它:

$ touch "file*"
$ touch "file**"
$ touch "file***"
$ tree
.
|-- file*
|-- file**
`-- file***

0 directory, 3 files
Run Code Online (Sandbox Code Playgroud)

在这个例子中不引用文件名只会给你一个被调用的文件file*(如果目录最初是空的),因为file**file***模式匹配那个file*名字。