了解-exec命令吗?

了解-exec命令吗?

这有效

find ./ -iname '*.c' -o -name '*.h' -o -name '*.l' -exec grep -irn test1 {} \;

如果我-exec与 ls 结合使用,它会告诉我这是不正确的选项。

#ls -exec touch {} \;
ls: invalid option -- 'e'
Try 'ls --help' for more information.

我的理解是否正确,该-exec选项仅由 find 使用,而不由其他命令使用?

答案1

了解命令的最佳方法是阅读其手册info ls/info findman ls/man find。或者了解每个的 POSIX 规范,了解所有不同实现应该通用的子集。

的语法find

find [options] <file1> [<file2>...] [predicates]

(某些find实现允许跳过<file1>

ls

ls [options] [<file1> [<file2>...]]

(其中[...]表示可选部分)。

标准选项是单个字母,并用 引入-。有些接受争论,有些则不接受。选项可以组合在一个参数中。比如ls -l -d可以写成ls -ld.

所以你可以看到-exec永远不可能是一个选项,因为find会将其解释为-e -x -e -c(或者可能-e -x ec如果该-x选项接受参数)。

一些工具实现支持长的选项,但这些选项带有前缀,--而不是以-避免这种冲突。例如,GNUfind和 GNUls都支持--help 选项

对于find, -execPOSIX 称之为谓词。它不是一个选项。它是表达它位于文件列表之后,用于确定选择哪些文件以及对它们执行什么操作。

find还支持一些选项(文件列表)如-L/-H会影响其全局行为。

ls没有概念谓词也不表达用于选择文件。它的行为仅受选项。没有任何选项可以让您ls执行任意命令。

顺便说一句,您的代码存在一些问题:

  • -a(省略时隐含)优先于-o,因此您-exec只会针对*.l文件运行。看具有多个“-name”和“-exec”的“find”仅执行“-name”的最后匹配项
  • -r曾经用于grep.这是一些grep实现支持的非标准选项,用于find完成工作并在目录中查找文件。虽然如果找到的文件都不find属于目录类型,则可能无害,但可能不需要。
  • 使用{} \;语法,您可以grep为每个文件运行一个。这是非常低效的,这也意味着grep不会显示文件的名称(除非-r上面启动)
  • 请注意,这-iname是一个非标准扩展(info find如果它是 GNU 扩展,您可能会在系统中找到它,但在 POSIX 规范中找不到它)。
  • 由于您没有使用-type谓词,find因此将报告任何类型的文件,而不仅仅是常规文件。这可能包括目录、设备、fifo...使用-type f会将搜索限制为常规的文件。使用 GNU find,您还可以用来-xtype f选择在符号链接解析后最终成为常规的文件。

为了解决这些问题,你可以这样做:

find . -name '*.[cChl]' -type f -exec grep -in test1 /dev/null {} +

答案2

正如 的手册页所find描述的那样,而 的手册页ls完全没有描述,-exec是一个特定于 的参数find。这就是为什么-exec可以与 一起使用find,但不能与 一起使用ls

的手册页find说:

   -exec command ;
          Execute command; true if 0 status is returned.  All following arguments to find are taken to be arguments to the command until an argument consisting of `;' is encountered.  The string `{}' is
          replaced  by  the  current  file name being processed everywhere it occurs in the arguments to the command, not just in arguments where it is alone, as in some versions of find.  Both of these
          constructions might need to be escaped (with a `\') or quoted to protect them from expansion by the shell.  See the EXAMPLES section for examples of the use of the -exec option.  The specified
          command is run once for each matched file.  The command is executed in the starting directory.   There are unavoidable security problems surrounding use of the -exec action; you should use the
          -execdir option instead.

   -exec command {} +
          This variant of the -exec action runs the specified command on the selected files, but the command line is built by appending each selected file name at the end; the total  number  of  invoca‐
          tions  of the command will be much less than the number of matched files.  The command line is built in much the same way that xargs builds its command lines.  Only one instance of `{}' is al‐
          lowed within the command.  The command is executed in the starting directory.  If find encounters an error, this can sometimes cause an immediate exit, so some pending commands may not be  run
          at all.  This variant of -exec always returns true.

   -execdir command ;

   -execdir command {} +
          Like  -exec,  but the specified command is run from the subdirectory containing the matched file, which is not normally the directory in which you started find.  This a much more secure method
          for invoking commands, as it avoids race conditions during resolution of the paths to the matched files.  As with the -exec action, the `+' form of  -execdir  will  build  a  command  line  to
          process more than one matched file, but any given invocation of command will only list files that exist in the same subdirectory.  If you use this option, you must ensure that your $PATH envi‐
          ronment variable does not reference `.'; otherwise, an attacker can run any commands they like by leaving an appropriately-named file in a directory in which you will run -execdir.   The  same
          applies to having entries in $PATH which are empty or which are not absolute directory names.  If find encounters an error, this can sometimes cause an immediate exit, so some pending commands
          may not be run at all. The result of the action depends on whether the + or the ; variant is being used; -execdir command {} + always returns true, while -execdir command  {}  ;  returns  true
          only if command returns 0.

ls命令不接受这样的参数。

相关内容