如果我想清空一个目录,有什么理由我不应该删除它并重新创建它吗?

时间:2017-02-05 03:22:46

标签: c linux rm

我已经查看了这两个线程来清空目录:

但是,清空作为这些线程的答案给出的目录的函数非常复杂,并且一个答案可能会遇到堆栈溢出。

当我考虑删除和添加目录时,我正在考虑在C和Linux平台上进行。但是,如果你想在Windows上解释这背后的原因,我也会很感激。 这是我要实现的代码:

system( "rm -rf /some/directory" )
mkdir("/some/directory", 0700);

这似乎更简单了。我什么理由不使用它?效率远远低于它的效率吗?

1 个答案:

答案 0 :(得分:4)

rm -fr /some/directory命令必须为您执行递归工作。使用该命令比编写自己的代码要做同样的工作要简单得多 - 它体现了懒惰的优点,并利用程序规模的代码重用。 (您不能在目录上使用rmdir()系统调用,除非它已经为空。)。所以这并非完全不合理。

一个问题是安全性:有人可以在您的路径上替换系统的rm命令吗?在Unix上,你的路径中首先是/bin/usr/bin,还是先做其他目录?

如果您认为使用/bin/rm(或/usr/bin/rm)足够安全,那么这可能是比未经修饰的rm更好的选择,但总的来说,这并不算太糟糕。

另一个问题是安全性的另一个方面 - 您是否可以实际删除并创建目录?你能写一下/some吗?如果删除并重新创建/some/directory,您是否应保留当前所有者,组和权限?在这些操作之后,该目录将由进程的有效UID拥有; if是否属于具有进程有效GID的组(除非在/some目录中设置了粘滞位 - 或者除非您在macOS上);权限将由0777的当前设置修改为umask()

如果这些问题不重要或可以绕过,那么删除和重新创建是合理的。

扩展上述评论:

  

当你在评论中提到system()来电时,我不知道你在说什么。

system()函数通过命令解释器执行作为参数传递的字符串。当你编写代码时,你必须考虑当有人恶意试图让你运行代码时它会出现什么问题。当您编写"rm -fr /some/directory"时,您依赖于shell找到正常的rm命令并正常工作。但是,如果您的PATH具有$HOME/bin:/bin:/usr/bin之类的值(以便您自己的私有bin目录中的命令优先于系统提供的命令),那么如果用户可以将自己的脚本安装为$HOME/bin/rm,他们可以使用您的权限执行任意代码 - 这可以让他们在以后保留您拥有的所有权限的情况下进入系统。他们甚至可能清理(大部分)曾经有$HOME/bin/rm脚本的证据。

避免此类问题的一种方法是请求"/bin/rm -fr /some/directory"(除非rm/usr/bin,而不是/bin,当然)。这可以说更安全。曾经有IFS环境变量可用的攻击;这些都是由现代shell绝对的,它们不使用IFS的任何继承值。

请注意,一个问题是解释rm命令是否成功。 -fr选项意味着它将在几乎所有情况下报告成功 - 但如果目录没有消失,则mkdir("/some/directory", 0777)呼叫将失败。

  

至于/some/directory的安全性,我对你要说的内容的理解是,可以选择错误的目录。我无法想象会发生什么。

假设您确实有权修改/some目录(您需要能够删除/some/directory),并且您可以修改旧版本{的所有子目录{1}},然后您可以从用户/some/directory拥有的/some/directory,群组victim和权限775开始,而在命令和系统调用之后(请注意witless }是函数而不是系统调用; system()是系统调用)成功,目录可能由用户mkdir(),组victor和权限0777拥有。这可能是不太理想。如果您不想破坏此类权限设置,您可能不希望使用删除和重新创建技术 - 或者,不是这样一个简单的技术,如此示例所示。然后,您必须更加努力地删除目录的内容而不修改这些属性。您可以扫描目录(mischiefopendir()readdir()并在每个名称上调用closedir() - 或名称集 - 以便在不删除目录本身的情况下彻底清理。它具有混合复杂性。它比简单地删除和重新创建更加繁琐,但远不如在多个级别处理完全递归删除那么繁琐。

正如我之前所说,你必须决定这些问题是否重要。重要的是你要意识到存在问题,并且你已经就是否处理问题以及如何处理问题做出了有意识(并且知情)的决定。

请记住,如果您的程序可以使用root(管理员)权限运行,那么要小心是非常重要的 - 但即使只有普通的凡人用户也会运行该程序,它仍然很重要。