Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash &引用;查找-mtime+;5“xargs rm-rf”字样;销毁整个目录,即使存在比5天更新的文件_Bash_Unix_Server_Synology - Fatal编程技术网

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系统<代码>-删除