我正在尝试编写一个查找文件和目录的 find 命令,问题是我只得到文件或错误,具体取决于命令中的某些变量。
该命令什么也不输出:
find '/mnt/downloads/cache/' -depth -mindepth 1 \( -type f ! -exec fuser -s {} \; \) -o \( -type d -empty \) -print
这是因为这两个过滤器没有封装在()中。为什么需要双引号?
此命令仅输出文件,但不输出目录:
find '/mnt/downloads/cache/' -depth -mindepth 1 \( \( -type f ! -exec fuser -s {} \; \) -o \( -type d -empty \) \) -print
封装两个参数的额外括号是唯一的区别。
该命令的最后一个变体会导致错误:
find '/mnt/downloads/cache/' -depth -mindepth 1 \( \( -type f ! -exec fuser -s {} \; \) -o \( -type d -empty {} \) \) -print
find: paths must precede expression: {}
为什么在目录测试后添加第二组 {} 会导致此错误?
固定命令:
find "/mnt/downloads/cache" -depth -mindepth 1 \( \
-type f \! -exec fuser -s '{}' \; -o \
-type d \! -empty \) \
-print
答案1
既然隐含了和( -a
) 的优先级高于-o
,第一个表达式中的右侧-o
被视为一个单位或者操作,即:
\( -type f ! -exec fuser -s {} \; \) -o \( -type d -empty \) -print
其作用与此相同:
\( -type f ! -exec fuser -s {} \; \) -o \( -type d -empty -print \)
因此,对于文件,它运行fuser
,对于目录,它打印它们的名称。
第二:
\( \( -type f ! -exec fuser -s {} \; \) -o \( -type d -empty \) \) -print
有显式括号,但不需要内部括号,这是相等的:
\( -type f ! -exec fuser -s {} \; -o -type d -empty \) -print
它应该打印所有fuser
返回虚假值(!= 0,由 反转!
)的空目录和文件。
在第三个中 ... -empty {} ...
,其中{}
被视为路径名,错误消息告诉您问题是什么。