我已经查看了这两个线程来清空目录:
但是,清空作为这些线程的答案给出的目录的函数非常复杂,并且一个答案可能会遇到堆栈溢出。
当我考虑删除和添加目录时,我正在考虑在C和Linux平台上进行。但是,如果你想在Windows上解释这背后的原因,我也会很感激。 这是我要实现的代码:
system( "rm -rf /some/directory" )
mkdir("/some/directory", 0700);
这似乎更简单了。我什么理由不使用它?效率远远低于它的效率吗?
答案 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拥有。这可能是不太理想。如果您不想破坏此类权限设置,您可能不希望使用删除和重新创建技术 - 或者,不是这样一个简单的技术,如此示例所示。然后,您必须更加努力地删除目录的内容而不修改这些属性。您可以扫描目录(mischief
,opendir()
,readdir()
并在每个名称上调用closedir()
- 或名称集 - 以便在不删除目录本身的情况下彻底清理。它具有混合复杂性。它比简单地删除和重新创建更加繁琐,但远不如在多个级别处理完全递归删除那么繁琐。
正如我之前所说,你必须决定这些问题是否重要。重要的是你要意识到存在问题,并且你已经就是否处理问题以及如何处理问题做出了有意识(并且知情)的决定。
请记住,如果您的程序可以使用root(管理员)权限运行,那么要小心是非常重要的 - 但即使只有普通的凡人用户也会运行该程序,它仍然很重要。