例如,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
设置failglob
shell 选项将使 shell 抱怨:shopt -s failglob
$ shopt -s failglob
$ touch 123*
bash: no match: 123*
默认情况下,等效选项在zsh
shell 中处于打开状态。
nullglob
在bash
(或)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*
名称匹配。