查找:将 -depth 与 -prune 结合起来以提供 cpio

查找:将 -depth 与 -prune 结合起来以提供 cpio

我正在构建一个备份脚本,其中某些目录不应包含在备份存档中。

cd /;
find . -maxdepth 2 \ 
    \( -path './sys' -o -path './dev' -o -path './proc' -o -path './media' -o -path './mnt' \) -prune \
-o -print

这只会找到我想要的文件和目录。

问题是cpio应该提供以下选项,以避免恢复文件时出现权限问题。

find ... -depth ....

如果我添加该-depth选项,返回的文件和目录将包括我想要避免的文件和目录。

我真的不明白查找手册中的这些句子:

-prune True;  if  the  file is a directory, do not descend into it. If
              -depth is given, false; no  effect.   Because  -delete  implies
              -depth, you cannot usefully use -prune and -delete together.

答案1

手册上的解释是这样的:

当到达与您的表达式find匹配的目录时,将避免进入其中。所以会去-path-prunefind

/             ok, go inside
/home         ok, go inside
/home/xxxx    ok, go inside
/tmp          don't go inside
/var          ..etc...

但是当您使用 时-depth,它会在目录本身之前处理目录内部。所以当为时已晚时它会匹配路径:

/home/xxxx
/home         ok, go inside (it already went)
/tmp/zzzz     didn't match "-path /tmp", so it's ok
/tmp          don't go inside (too late!)
/var          ..etc...
/

要解决这个问题你可以尝试:

  1. 只需添加带有通配符的新-path表达式即可。这样做的缺点是无论如何都会遍历这些子目录,只是不打印(并且它们的遍历可能会触发警告)

    find ... \( -path './sys' -o -path './sys/*' -o -path './dev' -o -path './dev/*' ... \) -prune ...

  2. 不要枚举要避免的目录,而是枚举要打印的目录!

    find /bin /boot /etc /home /lib ...

答案2

安格斯的回答解释为什么-depth不适合您并提出解决方案。

看起来您想要遍历整个安装,但省略特殊的文件系统,例如/proc/sys以及外部设备。有一个更好的方法来做到这一点:使用-xdevprimary onfind告诉它不要下降到安装点。如果您想在备份中包含一些已安装的文件系统,请明确列出它们。

find / /home -xdev -depth -print

答案3

第一步,我们拒绝特定目录,然后在其余目录上调用 find 并使用 -depth 来获取所需的格式:

cd / && \
find . -maxdepth 1 -type d \
   \( -name sys -o -name dev -o -name proc -o -name media -o -name mnt \) -prune -o \
   ! -name . -exec sh -c 'find "$1" -depth' {} {} \;

答案4

-regex如果您的支持,则使用find

find . -depth [...] -regex '\./\(sys\|dev\|proc\|media\|mnt\)\(/.*\)?' -prune -o -print

请注意,这-regex不是 POSIX,并且可能不一定在所有地方都受支持。此外,目录的内容仍将被遍历。

相关内容