Bash &引用;查找-mtime+;5“xargs rm-rf”字样;销毁整个目录,即使存在比5天更新的文件
我有一系列文件夹、子文件夹和文件,如下所示:Bash &引用;查找-mtime+;5“xargs rm-rf”字样;销毁整个目录,即使存在比5天更新的文件,bash,unix,server,synology,Bash,Unix,Server,Synology,我有一系列文件夹、子文件夹和文件,如下所示: year_folder month1_folder day1_folder filea, fileb day2_folder filea month2_folder 我想删除超过X天的文件夹和文件。 我试过了 find /c/Documents/year_folder -mtime +5 | xargs rm -rf 此命令行在我的测试文件夹(在我的计算机上本
year_folder
month1_folder
day1_folder
filea, fileb
day2_folder
filea
month2_folder
我想删除超过X天的文件夹和文件。
我试过了
find /c/Documents/year_folder -mtime +5 | xargs rm -rf
此命令行在我的测试文件夹(在我的计算机上本地)上运行良好。
但当我在synology上运行脚本时,不知怎么的,它删除了整年的文件夹
不幸的是,我不知道如何在synology服务器上测试我的脚本,以了解我做错了什么。使用GNU扩展
将其分为两部分:
- 删除超过五天的文件(仅!)
# for GNU find; see below for POSIX find "$root" -type f -mtime +5 -delete
- 删除空目录
# for GNU find; see below for POSIX find "$root" -depth -type d -empty -delete
rm-rf
时,您正在删除整个目录,而目录本身已经五天没有更新了。但是,如果您创建或修改a/b/c
,则不会更新a
的修改时间(或者,在不需要更新目录本身的修改情况下,甚至不需要更新a/b
)——因此,递归应用“修改时间早于五天”规则时,它是破坏性的
上面唯一需要注意的是,它可能不会在运行时删除多层空目录——也就是说,如果a/b/c
为空,并且a/b
为空而不是c
,那么在第一次运行时只能删除c
,并且在删除a/b
之前可能需要再次调用
支持基线POSIX POSIX
find
不支持-delete
。因此,第一个命令变为:
find "$root" -type f -mtime +5 -exec rm -rf -- {} +
类似地,它不支持-empty
。因为当传递非空目录时,rmdir
将失败,但是,很容易让引用非空目录的实例失败:
find "$root" -depth -type d -exec rmdir -- {} +
如果你不喜欢这样做,事情就会变得更棘手。使用shell测试每个目录是否为空的实现可能如下所示:
find "$root" -depth -type d -exec sh -c '
rmdir_if_empty() {
dir=$1
set -- "$dir"/* # replace argument list w/ glob result
[ "$#" -gt 1 ] && return # globbed to multiple results: nonempty
{ [ -e "$1" ] || [ -L "$1" ]; } && return # globbed to one result that exists: nonempty
rmdir -- "$dir" # neither of the above: empty, so delete.
}
for arg; do
rmdir_if_empty "$arg"
done
' _ {} +
使用GNU扩展
将其分为两部分:
- 删除超过五天的文件(仅!)
# for GNU find; see below for POSIX find "$root" -type f -mtime +5 -delete
- 删除空目录
# for GNU find; see below for POSIX find "$root" -depth -type d -empty -delete
rm-rf
时,您正在删除整个目录,而目录本身已经五天没有更新了。但是,如果您创建或修改a/b/c
,则不会更新a
的修改时间(或者,在不需要更新目录本身的修改情况下,甚至不需要更新a/b
)——因此,递归应用“修改时间早于五天”规则时,它是破坏性的
上面唯一需要注意的是,它可能不会在运行时删除多层空目录——也就是说,如果a/b/c
为空,并且a/b
为空而不是c
,那么在第一次运行时只能删除c
,并且在删除a/b
之前可能需要再次调用
支持基线POSIX POSIX
find
不支持-delete
。因此,第一个命令变为:
find "$root" -type f -mtime +5 -exec rm -rf -- {} +
类似地,它不支持-empty
。因为当传递非空目录时,rmdir
将失败,但是,很容易让引用非空目录的实例失败:
find "$root" -depth -type d -exec rmdir -- {} +
如果你不喜欢这样做,事情就会变得更棘手。使用shell测试每个目录是否为空的实现可能如下所示:
find "$root" -depth -type d -exec sh -c '
rmdir_if_empty() {
dir=$1
set -- "$dir"/* # replace argument list w/ glob result
[ "$#" -gt 1 ] && return # globbed to multiple results: nonempty
{ [ -e "$1" ] || [ -L "$1" ]; } && return # globbed to one result that exists: nonempty
rmdir -- "$dir" # neither of the above: empty, so delete.
}
for arg; do
rmdir_if_empty "$arg"
done
' _ {} +
顺便说一句,
find | xargs
通常是危险的,除非您使用find-print0 | xargs-0
。如果有人创建了一个目录,比如说,mkdir-p$'dummy/\n/etc/passwd\n/hello
,可能会导致脚本删除/etc/passwd
。(但是,使用现代find
,也没有必要:-exec…{}+
在将尽可能多的名称合并到一个调用上方面提供了与xargs
相同的性能优势。Re:您的测试文件夹,顺便说一句——如果您想重现问题,您可以使用touch--date
将您的本地目录设置为超过五天。顺便说一句,find | xargs
通常是危险的,除非您使用find-print0 | xargs-0
。如果有人创建了一个目录,比如说,mkdir-p$'dummy/\n/etc/passwd\n/hello
,可能会导致脚本删除/etc/passwd
。(但是,使用现代find
,也没有必要:-exec…{}+
在将尽可能多的名称合并到一个调用上提供了与xargs相同的性能优势。Re:your test folders,顺便说一句,如果您想重现问题,您可以使用touch--date
将本地目录的有效期设置为超过五天。这是一种在两个过程中删除文件和目录的好方法。然而,使用“-delete”选项而不是“-exec”要容易得多。@joming确实依赖于GNU系统<代码>-删除不存在。我不知道Synology提供了什么工具,所以我试图坚持标准。(也就是说,-empty
在基线查找中不存在,所以我做得不是很好)。谢谢,我使用了您的“支持基线”命令。分为两个步骤非常有效。@CharlesDuffy当你说“如果你创建或修改a/b/c,它不会更新a/b/c的修改时间(或者,如果修改不需要更新目录本身,甚至不需要更新a/b/c/b的修改时间)”时,它怎么会这样呢?我确实认为它是自然更新的。你有没有一个链接或解释让我更好地理解?这是一个很好的方法来删除文件和目录在两个过程。然而,使用“-delete”选项而不是“-exec”要容易得多。@joming确实依赖于GNU系统<代码>-删除