如何安全地递归删除 Windows 中的目录?

Art*_*nov 7 ntfs symbolic-link hardlink junction

NTFS支持各种链接,包括联结、硬链接、软链接等,所以这里有一个问题。

假设您正在递归删除实际上包含上述内容的目录。很容易想象,您的应用程序(无论是什么)不会删除所有连接点,而是会遍历它们并首先删除其中的所有文件,这些连接点、软链接可能会引导到您感兴趣的目录之外,等等。

这很容易导致重大数据丢失。

这是一个简单的例子。您安装了另一个安装了 Windows 的硬盘驱动器。

让我们检查一下内容D:\ProgramData

D:\ProgramData>dir /a
 Volume in drive D has no label.
 Volume Serial Number is 1234-4321

 Directory of D:\ProgramData

12/06/2021  12:56 PM    <DIR>          .
12/06/2021  12:56 PM    <DIR>          ..
07/14/2009  10:08 AM    <JUNCTION>     Application Data [C:\ProgramData]
07/14/2009  10:08 AM    <JUNCTION>     Desktop [C:\Users\Public\Desktop]
07/14/2009  10:08 AM    <JUNCTION>     Documents [C:\Users\Public\Documents]
07/14/2009  10:08 AM    <JUNCTION>     Favorites [C:\Users\Public\Favorites]
02/11/2016  03:51 PM    <DIR>          Microsoft
07/10/2019  03:00 AM    <DIR>          Microsoft Help
12/23/2019  04:04 PM    <DIR>          Package Cache
07/14/2009  10:08 AM    <JUNCTION>     Start Menu [C:\ProgramData\Microsoft\Windows\Start Menu]
07/14/2009  10:08 AM    <JUNCTION>     Templates [C:\ProgramData\Microsoft\Windows\Templates]
Run Code Online (Sandbox Code Playgroud)

现在,如果您尝试递归删除怎么办D:\ProgramData?我什至不会尝试这样做,因为我担心C:\ProgramData会首先被删除。

在 Linux 中rm -rf完美地处理了这个问题 - 它看到符号链接(到目录)并将符号链接作为文件删除,而不尝试遍历它们。

在 Windows 中递归删除此类目录的安全方法是什么?

rmdir /q /s?还有别的事吗?

bar*_*lop 0

尝试在命令提示符下使用 rmdir /s

我创建了一个目录 c:\abc1,其中包含一个文本文件。

我创建了一个目录 c:\test1 及其子目录 c:\test1\blah

在 c:\test1\blah 中,我尝试创建指向 c:\abc1 的链接、符号链接或联结链接。

然后,当我在 blah 上执行 rmdir /s 时,我检查了 c:\abc1,它的内容仍然存在。

因此,在 Windows 7 中测试的 cmd 提示符下的 rmdir /s 是安全的。

C:\>dir c:\abc1
 Volume in drive C has no label.
 Volume Serial Number is 4645-5DCE

 Directory of c:\abc1

28/12/2021  19:45    <DIR>          .
28/12/2021  19:45    <DIR>          ..
28/12/2021  19:45                 6 a.txt
               1 File(s)              6 bytes
               2 Dir(s)  137,425,338,368 bytes free

C:\>cd test
The system cannot find the path specified.

C:\>cd test1

C:\test1>dir
 Volume in drive C has no label.
 Volume Serial Number is 4645-5DCE

 Directory of C:\test1

28/12/2021  19:45    <DIR>          .
28/12/2021  19:45    <DIR>          ..
28/12/2021  19:46    <DIR>          blah
               0 File(s)              0 bytes
               3 Dir(s)  137,425,338,368 bytes free

C:\test1>cd blah

C:\test1\blah>dir
 Volume in drive C has no label.
 Volume Serial Number is 4645-5DCE

 Directory of C:\test1\blah

28/12/2021  19:46    <DIR>          .
28/12/2021  19:46    <DIR>          ..
               0 File(s)              0 bytes
               2 Dir(s)  137,425,338,368 bytes free

C:\test1\blah>mklink /?
Creates a symbolic link.

MKLINK [[/D] | [/H] | [/J]] Link Target

        /D      Creates a directory symbolic link.  Default is a file
                symbolic link.
        /H      Creates a hard link instead of a symbolic link.
        /J      Creates a Directory Junction.
        Link    specifies the new symbolic link name.
        Target  specifies the path (relative or absolute) that the new link
                refers to.

C:\test1\blah>mklink /d c:\abc1
The syntax of the command is incorrect.
Creates a symbolic link.

MKLINK [[/D] | [/H] | [/J]] Link Target

        /D      Creates a directory symbolic link.  Default is a file
                symbolic link.
        /H      Creates a hard link instead of a symbolic link.
        /J      Creates a Directory Junction.
        Link    specifies the new symbolic link name.
        Target  specifies the path (relative or absolute) that the new link
                refers to.

C:\test1\blah>mklink /d qq c:\abc1
symbolic link created for qq <<===>> c:\abc1

C:\test1\blah>dir
 Volume in drive C has no label.
 Volume Serial Number is 4645-5DCE

 Directory of C:\test1\blah

28/12/2021  19:47    <DIR>          .
28/12/2021  19:47    <DIR>          ..
28/12/2021  19:47    <SYMLINKD>     qq [c:\abc1]
               0 File(s)              0 bytes
               3 Dir(s)  137,425,469,440 bytes free

C:\test1\blah>dir qq
 Volume in drive C has no label.
 Volume Serial Number is 4645-5DCE

 Directory of C:\test1\blah\qq

28/12/2021  19:45    <DIR>          .
28/12/2021  19:45    <DIR>          ..
28/12/2021  19:45                 6 a.txt
               1 File(s)              6 bytes
               2 Dir(s)  137,425,469,440 bytes free

C:\test1\blah>cd ..

C:\test1>rmdir /s blah
blah, Are you sure (Y/N)? y

C:\test1>dir c:\abc1
 Volume in drive C has no label.
 Volume Serial Number is 4645-5DCE

 Directory of c:\abc1

28/12/2021  19:45    <DIR>          .
28/12/2021  19:45    <DIR>          ..
28/12/2021  19:45                 6 a.txt
               1 File(s)              6 bytes
               2 Dir(s)  137,425,379,328 bytes free

C:\test1>cd blah
The system cannot find the path specified.

C:\test1>md blah

C:\test1>dir
 Volume in drive C has no label.
 Volume Serial Number is 4645-5DCE

 Directory of C:\test1

28/12/2021  19:47    <DIR>          .
28/12/2021  19:47    <DIR>          ..
28/12/2021  19:47    <DIR>          blah
               0 File(s)              0 bytes
               3 Dir(s)  137,424,666,624 bytes free

C:\test1>cd blah

C:\test1\blah>dir
 Volume in drive C has no label.
 Volume Serial Number is 4645-5DCE

 Directory of C:\test1\blah

28/12/2021  19:47    <DIR>          .
28/12/2021  19:47    <DIR>          ..
               0 File(s)              0 bytes
               2 Dir(s)  137,424,666,624 bytes free

C:\test1\blah>mklink /?
Creates a symbolic link.

MKLINK [[/D] | [/H] | [/J]] Link Target

        /D      Creates a directory symbolic link.  Default is a file
                symbolic link.
        /H      Creates a hard link instead of a symbolic link.
        /J      Creates a Directory Junction.
        Link    specifies the new symbolic link name.
        Target  specifies the path (relative or absolute) that the new link
                refers to.

C:\test1\blah>mklink /J ww c:\abc1
Junction created for ww <<===>> c:\abc1

C:\test1\blah>dir
 Volume in drive C has no label.
 Volume Serial Number is 4645-5DCE

 Directory of C:\test1\blah

28/12/2021  19:48    <DIR>          .
28/12/2021  19:48    <DIR>          ..
28/12/2021  19:48    <JUNCTION>     ww [c:\abc1]
               0 File(s)              0 bytes
               3 Dir(s)  137,424,715,776 bytes free

C:\test1\blah>dir ww
 Volume in drive C has no label.
 Volume Serial Number is 4645-5DCE

 Directory of C:\test1\blah\ww

28/12/2021  19:45    <DIR>          .
28/12/2021  19:45    <DIR>          ..
28/12/2021  19:45                 6 a.txt
               1 File(s)              6 bytes
               2 Dir(s)  137,424,715,776 bytes free

C:\test1\blah>cd ..

C:\test1>rmdir /s blah
blah, Are you sure (Y/N)? y

C:\test1>dir c:\abc1
 Volume in drive C has no label.
 Volume Serial Number is 4645-5DCE

 Directory of c:\abc1

28/12/2021  19:45    <DIR>          .
28/12/2021  19:45    <DIR>          ..
28/12/2021  19:45                 6 a.txt
               1 File(s)              6 bytes
               2 Dir(s)  137,424,740,352 bytes free

C:\test1>
Run Code Online (Sandbox Code Playgroud)

实际上,您应该能够非常轻松地自己进行测试。

一条评论提到 powershell rmdir 是不同的。我不能对 powershell 发表太多评论,我不太使用它。我看到 powershell 的 rmdir 确实给出了不同的输出,例如 rmdir 说“cmdlet Remove-Item at command pipeline...”所以似乎与 cmd 非常不同,我不熟悉它。