如果我想清空一个目录,有什么理由不应该删除它并重新创建它?
If I want to empty a directory, is there any reason I shouldn't remove it and recreate It?
我查看了这两个用于清空目录的线程:
Removing a non empty directory programmatically in C or C++
Delete folder and all files/subdirectories
然而,清空目录的函数非常复杂,一个答案可能会遇到堆栈溢出。
当我考虑删除和添加目录时,我正在考虑用 C 语言在 Linux 平台上进行。但是,如果您还想在 Windows 上解释这背后的原因,我也将不胜感激。
这是我要实现的代码:
system( "rm -rf /some/directory" )
mkdir("/some/directory", 0700);
这看起来简单多了。我有什么理由不使用它?它的效率远不如表面上看吗?
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()
的当前设置修改。
如果这些问题不重要,或者是可以规避的,那么删除并重新创建是合理的。
扩展以上评论:
When you mentioned the system()
call in your comment, I had no idea what you were talking about.
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)
调用将失败。
As for the security of the /some/directory
, my understanding of what you're trying to say, is that the wrong directory could be selected. I just can't imagine how that would occur.
假设您确实有权修改 /some
目录(您需要该权限才能删除 /some/directory
),并且您可以修改所有 sub-directories /some/directory
的旧版本,那么您可能会从用户 victim
、组 witless
拥有的 /some/directory
和权限 775 开始,而在命令和系统调用之后(请注意system()
是一个函数而不是系统调用;mkdir()
是一个系统调用)都成功了,该目录可能由用户 victor
、组 mischief
拥有并具有权限 0777 . 这可能不太理想。如果您不想破坏此类权限设置,您可能不想使用删除和重新创建技术 — 或者,不是本示例所示的 simple-minded 技术。然后,您将不得不更加努力地删除目录的内容而不修改这些属性。您可以扫描目录 (opendir()
、readdir()
、closedir()
并在每个名称(或名称集)上调用 rm
以彻底清理而不删除目录本身。这具有混合复杂性。它比简单地删除和重新创建更繁琐,但远不如处理多个级别的完全递归删除那么繁琐。
正如我之前所说,您必须决定这些问题是否重要。重要的是您要意识到问题的存在,并且您已就是否处理这些问题以及如何处理这些问题做出有意识(且知情)的决定。
请记住,如果您的程序可能 运行 具有 root(管理员)权限,那么请务必小心——但即使只有普通普通用户会 运行,这仍然很重要程序。
我查看了这两个用于清空目录的线程:
Removing a non empty directory programmatically in C or C++
Delete folder and all files/subdirectories
然而,清空目录的函数非常复杂,一个答案可能会遇到堆栈溢出。
当我考虑删除和添加目录时,我正在考虑用 C 语言在 Linux 平台上进行。但是,如果您还想在 Windows 上解释这背后的原因,我也将不胜感激。 这是我要实现的代码:
system( "rm -rf /some/directory" )
mkdir("/some/directory", 0700);
这看起来简单多了。我有什么理由不使用它?它的效率远不如表面上看吗?
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()
的当前设置修改。
如果这些问题不重要,或者是可以规避的,那么删除并重新创建是合理的。
扩展以上评论:
When you mentioned the
system()
call in your comment, I had no idea what you were talking about.
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)
调用将失败。
As for the security of the
/some/directory
, my understanding of what you're trying to say, is that the wrong directory could be selected. I just can't imagine how that would occur.
假设您确实有权修改 /some
目录(您需要该权限才能删除 /some/directory
),并且您可以修改所有 sub-directories /some/directory
的旧版本,那么您可能会从用户 victim
、组 witless
拥有的 /some/directory
和权限 775 开始,而在命令和系统调用之后(请注意system()
是一个函数而不是系统调用;mkdir()
是一个系统调用)都成功了,该目录可能由用户 victor
、组 mischief
拥有并具有权限 0777 . 这可能不太理想。如果您不想破坏此类权限设置,您可能不想使用删除和重新创建技术 — 或者,不是本示例所示的 simple-minded 技术。然后,您将不得不更加努力地删除目录的内容而不修改这些属性。您可以扫描目录 (opendir()
、readdir()
、closedir()
并在每个名称(或名称集)上调用 rm
以彻底清理而不删除目录本身。这具有混合复杂性。它比简单地删除和重新创建更繁琐,但远不如处理多个级别的完全递归删除那么繁琐。
正如我之前所说,您必须决定这些问题是否重要。重要的是您要意识到问题的存在,并且您已就是否处理这些问题以及如何处理这些问题做出有意识(且知情)的决定。
请记住,如果您的程序可能 运行 具有 root(管理员)权限,那么请务必小心——但即使只有普通普通用户会 运行,这仍然很重要程序。