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

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

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

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

答案1

当在 shell 中使用不带引号的模式时abc*,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*

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

nullglobbash(或)NULL_GLOB中设置shell 选项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**file***模式与第一个file*名称匹配。

相关内容