如何安全且简单地在Ruby中删除目录?

28

我想删除一个目录,该目录可能包含文件或其他目录。查看 Ruby 文档后,我发现 Dir.rmdir 不能删除非空目录。是否有便捷的方法可以让我做到这一点?或者我需要编写递归方法来检查目录下面的所有内容?

4个回答

56
require 'fileutils'

FileUtils.rm_rf(dir)

5
请注意,文档中对此进行了警告:如果您不将 :secure 作为 rm_rf 的选项传递,可能会暴露漏洞。 - yagni
1
@BKewl 参考资料是什么? - kingsfoil
3
请参考 http://ruby-doc.org/stdlib-1.9.3/libdoc/fileutils/rdoc/FileUtils.html#method-c-rm_rf 和 http://ruby-doc.org/stdlib-1.9.3/libdoc/fileutils/rdoc/FileUtils.html#method-c-rm_r。 - yagni
2
仅供参考,我发现在Windows和Ruby 1.9.3(至少)中,FileUtils.rm_rf将遵循链接(在这种情况下是符号链接)并删除那些文件和文件夹。这是通过使用CreateSymbolicLinkW创建符号链接,然后针对包含符号链接的父目录运行FileUtils.rm_rf来发现的。这不是完全预期的行为。 - ferventcoder
有没有一种方法可以不删除符号链接的目标,而只删除链接文件本身? - Semimono
显示剩余3条评论

3

纯 Ruby 方法:

需要引入 'fileutils' 库

FileUtils.rm_rf("/directory/to/go") 可以删除指定目录下的所有文件和子目录。

如果需要线程安全: (警告,会更改当前工作目录)

FileUtils.rm_rf("directory/to/go", :secure=>true) 可以删除指定目录下的所有文件和子目录,并确保在多线程环境下安全执行。


fiileutils 需要 >= 2.3.0 版本,但不是所有平台都有作为标准包可用,例如 CentOS 7。 - Christoph Henrici

0

如果有人在寻找 @ferventcoder 评论中的答案 -

顺便提一下,我发现在 Windows 和 Ruby 1.9.3(至少如此)上,FileUtils.rm_rf 将会跟随链接(在这种情况下是符号链接)并删除那些文件和文件夹。这是由于创建 CreateSymbolicLinkW 符号链接,然后运行 FileUtils.rm_rf 删除包含符号链接的父目录而发现的。这不是完全符合预期的行为。

– ferventcoder

最安全的方法是迭代路径并手动删除它。

def rec_del(path):

  1. 如果路径是文件,请调用 FileUtils.rm_rf - 即使在 Windows 中也可以安全删除
  2. 如果目录,则调用 Dir.rmdir,这将成功删除空目录和目录符号链接。否则,对于常规非空目录,将获得 ENOTEMPTY。
  3. 迭代该目录并为每个项调用 rec_del。
  4. 现在再次调用 Dir.rmdir,这将成功

-3

最懒的方法是:

def delete_all(path)
    `rm -rf "#{path}"`
end

不支持Windows系统。不必要地启动了两个子进程(一个shell和rm本身)。仅返回错误代码,而不是可能更详细的异常信息。(您可能需要删除此答案,@AnaBetts。) - toolforger
至少它可以在不需要 ruby >= 2.3.0 的情况下工作。类似的逻辑可以用于实现需要支持的不同操作系统变体。 - Christoph Henrici

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接