如果没有给出路径,为什么 find 打印前导'./'?

n.r*_*.r. 14 find

如果没有给出路径,为什么会find打印出导致./结果的结果?

$ find
./file1
./file2
./file3
Run Code Online (Sandbox Code Playgroud)

不打印出来的原因是什么?

$ find
file1
file2
file3
Run Code Online (Sandbox Code Playgroud)

Tho*_*key 17

你看到这个的原因是因为 GNU 的开发者选择在没有给出路径时提供“合理”的行为。相比之下,POSIX没有声明该参数是可选的:find find

find实用程序应从path 指定的每个文件递归地下降目录层次结构,为遇到的每个文件评估由 OPERANDS 部分中描述的主要组成的布尔表达式。每个路径操作数都应按原样进行评估,包括所有尾随<slash>字符;层次结构中遇到的其他文件的所有路径名应由当前路径操作数的串联组成,一个<slash>如果当前路径操作数不是以一个结尾,则为相对于路径操作数的文件名。相对部分不应包含点或点-点组件,不包含尾随字符,并且<slash>路径名组件之间只有单个字符。

您可以在每个概要中看到不同之处。 GNU 有(按照惯例)方括号中的可选项目:

find [-H] [-L] [-P] [-D debugopts] [-Olevel] [starting-point...]
       [expression]
Run Code Online (Sandbox Code Playgroud)

而 POSIX 并不表示它可以是可选的:

find [-H|-L] path... [operand_expression...]
Run Code Online (Sandbox Code Playgroud)

在 GNU 程序中,这是在ftsfind.c

  如果(空)
    {
      /*
       * 我们在这里使用了一个临时变量,因为有些动作会修改
       * 临时路径。因此,如果我们使用字符串常量,
       * 我们得到一个核心转储。最好的例子是如果我们说
       *“find -printf %H”(注意,不是“find .-printf %H”)。
       */
      char defaultpath[2] = ".";
      返回查找(默认路径);
    }

"."为简单起见,使用文字。所以你会看到相同的结果

find
Run Code Online (Sandbox Code Playgroud)

find .
Run Code Online (Sandbox Code Playgroud)

因为(并且 POSIX 同意)给定的路径将用于作为结果的前缀(参见上面的连接)。

只需稍加工作,就可以确定首次添加该功能的时间;它出现在1996 年最初创建的“findutils”中(请参阅参考资料find.c):

+  /* If no paths are given, default to ".".  */
+  for (i = 1; i < argc && strchr ("-!(),", argv[i][0]) == NULL; i++)
+    process_top_path (argv[i]);
+  if (i == 1)
+    process_top_path (".");
+
+  exit (exit_status);
+}
Run Code Online (Sandbox Code Playgroud)

从 find 3.8 的变更日志中,这显然是

Sat Dec 15 19:01:12 1990  David J. MacKenzie  (djm at egypt)

        * find.c (main), util.c (usage): Make directory args optional,
        defaulting to "."
Run Code Online (Sandbox Code Playgroud)


Joh*_*024 11

通常,对文件进行后处理,在这种情况下,以./. 特别是,如果文件名以 开头-,则后续命令可以将该文件名解释为选项。 ./避免这种情况。

例如,考虑一个包含以下文件的目录:

$ ls
--link  --no-clobber
Run Code Online (Sandbox Code Playgroud)

现在,想象一下如果提供的文件名没有./前面的,这个命令将如何工作:

$ find -type f -exec cp -t ../ {} +
Run Code Online (Sandbox Code Playgroud)

我们可以用find它本身来说明问题。让我们在与上面相同的目录中运行它。以下工作:

$ find ./*
./--link
./--no-clobber
Run Code Online (Sandbox Code Playgroud)

以下失败:

$ find *
find: unknown predicate `--link'
Try 'find --help' for more information.
Run Code Online (Sandbox Code Playgroud)

  • 某些版本的`file` _demand_ 用户提供路径(如OS X 上的BSD find)。所以你通常需要明确地说像 `find 之类的东西。-type f ...`。从那里开始,对于某些版本的 find(如 GNU find)来说,默认为“.”并保持其他所有内容不变,这并不是一个很大的进步。 (3认同)