查找:“-exec rm {} \;” vs. "-delete" - 为什么前者被广泛推荐?

Lew*_*Fan 7 linux find

为什么那些文章find总是-exec rm {} \;在更短、更容易打字和阅读的情况下使用-delete,据我所知,似乎也能正常工作?

我知道有那里的情况rm 有一些选项一样-r -f,例如可以做一些更多的花样,但也有吨的普通例子-exec rm {} \;在教程所有过网,但几乎没有使用的例子-delete

我错过了什么?这有什么原因吗?

Kam*_*ski 15

tl;dr:-deletePOSIX 不需要,-exec是。


事实

POSIX 1003.1 手册页find指定-exec但不是-delete.

这意味着-exec几乎可以在任何地方工作。我会感到很惊讶的发现find-delete没有-exec。相反是很有可能的。特别是使用的轻量级系统busybox往往只提供基本的命令行选项。

例如,我的其中一台路由器上有一个 OpenWRT ,它可以find理解-exec,但不能理解-delete

没有-delete是不是一个大问题,当你有-exec rm …。另一方面-delete不能替代-exec一般。首先允许省略是一个明智的设计-delete


个人经验、观察和意见

以上应该-exec rm {} \;被广泛推荐的主要原因。次要的可能是滚雪球效应。用户阅读文章和示例,熟悉-exec并发布他们自己的命令(例如在这里超级用户)。他们中的一些人甚至可能不知道-delete存在。

我很少看到(或给出)诸如“您可以-delete改用”之类的评论。回答就像'谢谢,我不知道'。我不记得有任何回应“我知道,但这不是 POSIX”。


说了这么多,我-delete每次-exec rm {} \;出现时都会提到。原因是-delete不会产生一个新进程,而是为每个匹配的文件-exec rm {} \;调用一个单独的进程rm。如果您不能使用,-delete那么您的下一个想法应该是-exec rm {} +可以使用单个删除多个文件rmrm如果需要,它仍然会调用多次)。

为什么不-exec … +广泛推荐呢?这可能是因为它的局限性。我可以想象一个没有经验的用户会想“这适用于rm,让我使用它mv!” 然后-exec mv {} foo/ +不起作用,因为{}需要在最后,就在+. 用户感到沮丧并跑回妈妈Windows。


-delete我认为在超级用户这里推荐通常是安全的。大多数问题都指定了“大”操作系统,find那里的命令有丰富的选项。即使有一个用户find受限,我也可能会得到反馈。他或她说该解决方案对他们不起作用,我建议-exec rm …改为解释问题等。

推荐的独立文章-delete不会得到这样的反馈。如果遇到任何问题,用户只需转到 Google 返回的下一个链接即可。

  • 这是一篇写得很好的阐述。清晰、简洁、实用。谢谢您不辞辛苦。 (2认同)

Mic*_*iño 5

区别在于灵活性。如果您使用 -exec,那么您将为每个选定的文件执行一个命令。如果您使用 -exec 那么您可以灵活地应用其他查找选项。使用 -delete 时,您将被限制使用 -prune。此外,您放置的 -delete 会影响您的结果。请参阅下面的文档片段:

\n\n
-delete\n    Delete  files;  true  if removal succeeded.  If the removal failed, \n    an error message is issued.  If -delete fails, find\xe2\x80\x99s exit status will be\n        nonzero (when it eventually exits).  Use of -delete automatically turns on \n    the \xe2\x80\x98-depth\xe2\x80\x99 option.\n\n    Warnings: Don\xe2\x80\x99t forget that the find command line is evaluated as an \n    expression, so putting -delete first will make find try to delete every-\n    thing  below  the  starting  points  you  specified.   When testing a find \n    command line that you later intend to use with -delete, you should\n    explicitly specify -depth in order to avoid later surprises.  \n    Because -delete implies -depth, you cannot  usefully  use  -prune  and  -delete\n    together.\n\n-exec command ;\n    Execute  command;  true  if 0 status is returned.  All following arguments \n    to find are taken to be arguments to the command until an argument\n    consisting of \xe2\x80\x98;\xe2\x80\x99 is encountered.  The string \xe2\x80\x98{}\xe2\x80\x99 is replaced by the \n    current file name being processed everywhere it occurs in the arguments\n    to  the  command, not just in arguments where it is alone, as in \n    some versions of find.  Both of these constructions might need to be escaped\n    (with a \xe2\x80\x98\\\xe2\x80\x99) or quoted to protect them from expansion by the shell.  \n    See the EXAMPLES section for examples of the use of  the  -exec  option.\n    The specified command is run once for each matched file.  The \n    command is executed in the starting directory.   There are unavoidable security\n    problems surrounding use of the -exec action; you should use the -execdir \n    option instead.\n\n-exec command {} +\n    This variant of the -exec action runs the specified command on the \n    selected files, but the command line is built by appending  each  selected\n    file name at the end; the total number of invocations of the command \n    will be much less than the number of matched files.  The command line is\n    built in much the same way that xargs builds its command lines.  \n    Only one instance of \xe2\x80\x98{}\xe2\x80\x99 is allowed within the  command.   The  command  is\n    executed in the starting directory\n
Run Code Online (Sandbox Code Playgroud)\n