【问题标题】:bash find, only delete files - order of argumentsbash 查找,仅删除文件 - 参数顺序
【发布时间】:2015-06-14 03:28:05
【问题描述】:
假设今天是 4 月 8 日,我在 bash 中执行以下操作。
cd /tmp
mkdir hello
touch -d 2015-04-01 hello
然后,假设我想删除 /tmp 中所有超过一天的文件,但不是目录,我执行以下操作:
find /tmp -mtime +1 -delete -type f
如果不是文件,为什么目录“hello”会被删除?
谢谢!
【问题讨论】:
标签:
bash
find
positional-operator
find-util
【解决方案1】:
find 命令按顺序执行表达式。因为-delete 在-type 之前,所以永远不会到达-type。试试:
find /tmp -mtime +1 -type f -delete
【解决方案2】:
称它们为“选项”是可以理解的,但由于它们不是选项正是问题的原因,find' s 术语和概念值得仔细研究:
- 遵循输入路径的参数统称为表达式。
- 表达式由以下部分组成:
-
测试(例如,
-type f)
-
操作(例如,
-delete)
-
options(例如,
-maxdepth 1)- 请注意,这些选项不同于 标准 选项,这些选项必须在输入路径之前(例如, find -L /tmp ...)
- 注意:以上是 GNU
find 术语,它比 POSIX spec. for find 中的更细粒度,其中所有三个构造都由 single 名称,primaries(BSD find 也只是在其 man 页面中使用 primaries)。
-
运算符:
-a (-and) 用于逻辑 AND,-o (-or) 用于逻辑 OR,! (-not) 用于否定;括号中的替代形式不符合 POSIX,但受 GNU 和 BSD find 支持。
-
运算符将测试和操作组合成布尔表达式。
- 在没有显式运算符的情况下,测试和操作由隐式逻辑 AND (
-a) 连接。
-
-a 和 -o 应用 短路(见下文)
-
子表达式可以用
\(和\)分组来改变优先级(\-escaping是为了保护括号不被shell解释)。
-
优先级(最高优先):
\(...\)、!、-a、-o
-
关于测试和操作的顺序很重要。
-
相比之下,
find options 是 not 位置的,但 GNU find 默认情况下会发出警告,如果它们没有被放置before 测试和操作。为避免出现警告,并在总体上保持概念清晰,最好这样做。
-
每个测试和动作返回一个布尔值,并且短路应用:
- 在典型情况 - 隐含
-a - 这意味着一旦先前的测试或操作返回错误,则不会评估后续测试和操作:
find . -false -print # !! -print is NOT executed
- 同样,
-o (-or) 表达式的第二个操作数不会执行,如果第一个操作数返回 true:
find . -print -o -print # !! 2nd -print is NOT executed