我正在使用以下内容来查找和删除一组子卷:
find /.snapshots/ -name backup-* -type d -exec btrfs subvolume delete {} \;
它有效,但我从 find 中得到了意外的输出:
Delete subvolume (no-commit): '/.snapshots/backup-24-11-2021'
find: ‘/.snapshots/backup-24-11-2021’: No such file or directory
Delete subvolume (no-commit): '/.snapshots/backup-25-11-2021'
find: ‘/.snapshots/backup-25-11-2021’: No such file or directory
我不是unix的专业人士,所以对我来说有点令人费解,为什么会发生这种情况?
当
find
到达时/.snapshots/backup-24-11-2021
,它检查它是否是一个目录,如-type d
. 它是一个目录,find
因此btrfs subvolume delete /.snapshots/backup-24-11-2021
按照-exec …
. 完成后,find
刚刚访问了一个目录,因此它递归到该目录。毕竟,递归到目录是find
. 但是该目录刚刚被删除(按btrfs subvolume delete
)。所以find
注意到有问题并报告它。告诉
find
不要在您要删除的快照下递归。这通常适用于查找要删除的整个目录树。(注意:我还修复了
-name
子句周围缺少的引号。没有引号,在运行backup-*
时会扩展find
,因此如果当前目录有匹配的文件backup-*
,或者如果您使用的 shell 出错,该命令将不会执行预期的操作在不匹配的球体上。)但实际上,这可能是完全错误的命令。您正在指示
find
在/.snapshots
. 例如,如果有一个 directory/.snapshots/saved-for-posterity/usr/src/backup-app
,您的命令会指示find
callbtrfs subvolume delete /.snapshots/saved-for-posterity/usr/src/backup-app
,这是没有意义的。假设所有快照都是 的子目录/.snapshots
,通过-maxdepth 1
以避免进一步递归:那和之间的唯一区别
如果目前没有备份,这将
btrfs subvolume delete
使用文字参数调用。/.snapshots/backup-*
您收到错误消息是因为您删除了之前
find
有机会查看其中的目录。当find
包含现在删除的目录的目录完成后,它会尝试输入 egbackup-24-11-2021
,但由于“没有这样的文件或目录”错误而失败,因为它已经消失了。-depth
您可以通过使用with来解决这个问题find
,这会使该实用程序改为对目录进行深度优先搜索。查找和删除 eg/.snapshots/backup-25-11-2021
只会find
在查看该路径下的所有其他目录后发生。另请注意,我们需要将参数引用到
-name
测试中,因为它包含文件名通配符。另一种方法是使用
-prune
,即从搜索树中删除该路径,find
以便它find
不会尝试进入它。第三种方法,如果您的所有
backup-*
目录总是直接位于 下/.snapshots
,则根本不使用find
:上面的 shell 循环将调用
btrfs subvolume delete
与模式匹配的所有目录/.snapshots/backup-*
。在bash
shell 中,设置nullglob
shell 选项将导致 shell 删除任何不匹配的通配模式,而不是保留未扩展的模式。如果该命令
btrfs subvolume delete
能够将多个路径名作为参数,您甚至可以只做...如果没有与给定通配模式匹配的路径名,shell 中的
failglob
shell 选项将阻止命令执行。bash