find 命令中通配符的奇怪行为

Sin*_*osh 3 command-line bash find

globbing 是 shell 的一个特性吗?

我学会了如何在 find 命令中使用通配符,但今天我看到了一个奇怪的行为。

当我在搜索位置以外的任何地方时,我不需要单引号或双引号进行通配

$ pwd
/home
$ find / -name *c
...
it is ok
Run Code Online (Sandbox Code Playgroud)

$ pwd
/
$ find / -name *c
find: paths must precede expression: proc
Usage: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path...] [expression]
Run Code Online (Sandbox Code Playgroud)

发生什么事?

hee*_*ayl 12

当您使用未加引号(或未转义)*即 glob 标记*(任意数量的字符,即任何文件)时,shell 将扩展*到给定目录中的*c所有文件,如果是c. 所以当你运行时:

find / -name *c
Run Code Online (Sandbox Code Playgroud)

假设有三个.c文件在当前目录下,即foo.cbar.cspam.c,命令实际上将运行是:

 find / -name foo.c bar.c spam.c
Run Code Online (Sandbox Code Playgroud)

这是一个无效的命令,因为您可以看到它在单个-name选项后使用多个文件名。这就是您在 时发生的情况/

现在,虽然 at /home,大概没有*c文件存在,因此*c将保留glob 模式(在 中bash,这是依赖于 shell 的行为;在 中bash,您可以通过nullglob/ failglobshell 选项更改默认行为),因此命令findgets 是:

 find / -name *c
Run Code Online (Sandbox Code Playgroud)

这是一个有效的命令,预计正在运行。


现在,find您应该引用或转义任何 shell globbing 标记,因为您想find解释(扩展)这些标记,而不是事先由 shell 解释。因此,请执行以下任一操作:

find / -name '*c'
find / -name "*c"
find / -name \*c
Run Code Online (Sandbox Code Playgroud)