Bash memory" leak"当递归目录时

时间:2014-07-08 17:01:57

标签: linux macos bash fat32 hfs+

我目前正在尝试编写一个脚本,在rsync --max-size=4000000000完成其工作后执行一些后期处理,以允许完全备份到FAT32(这是唯一一个r / w的文件系统Windows / Mac / * nix)

我正在用Mac OS X和Linux编写bash;目前正在OS X上进行测试。代码在这里

https://github.com/taikedz/fullsync32/blob/master/fullsync32

脚本通过目录查找

  • 具有资源分支(HFS属性)
  • 的文件
  • 大于4 GB的文件

并在找到此类文件后,根据需要通过tar -czsplit处理这些文件,然后再将其复制。

我使用递归而不是find实用程序,因为测试文件上是否存在资源fork:它涉及检查特殊文件的大小。假设你有文件foo.txt;通过查看ls -l foo.txt/..namedfork/rsrc可以找到它的资源分支,并且查询长度是非零的。

基本结构是

recurse() {
  pushd "$1"
    for NODE in *; do
      if [ -d "$NODE" ]; then
        recurse "$NODE"
        continue
      fi
      # (process files here, with calls to split, tar and md5)
    done
  popd
}

recurse ./target/directory

问题

我前几天对着我的备份运行了这个并让它运行了几个小时。当我回来的时候,我发现我的备用11 GB的RAM已经用完了,交换了大约248 MB ......

我在谷歌周围查看了关于递归中bash内存泄漏的问题,除了几篇经常回答的论坛帖子外,没有找到太多......

其他添加结果(特定于Mac)是"非活动内存"保持不活动状态,系统运行缓慢...需要重新启动。

问题

  • 这种潜在的深度递归本身是一个坏主意吗?
  • 是否有一种巧妙的方法来迭代而不是在这种情况下递归?
  • 或者我是否完全错了?

您的投入非常感谢!

1 个答案:

答案 0 :(得分:2)

  

这种潜在的深度递归本身是一个坏主意吗?

Bash不是用于递归,但是没有问题递归到几千个级别,这足以通过文件系统递归。

然而,与所有语言一样,Bash无法通过前面find经过验证的循环检测来进行无限深度的非尾递归,就像你冒险一样。

  

是否有一种巧妙的方法来迭代而不是在这种情况下递归?

您可以迭代find输出:

find "$1" -print0 | while IFS= read -d '' -r filename
do
  echo "Operating on $filename"
done
  

如何使用find来执行测试

您可以使用-exec运行任意外部测试,此处调用bash:

find / -exec bash -c '[[ -s "$1/..namedfork/rsrc" ]]' _ {} \; -print