该命令dir /a
显示给定位置的所有文件和文件夹的列表。
但是它显示了连接点的类型<JUNCTION>
以及文件夹的符号链接。是否有任何命令可以区分并告诉我其中哪些<JUNCTION>
是连接点,哪些是符号链接以及哪些文件是硬链接?
答案1
为什么不使用连接点来自 SysInternals?它允许您列出特定文件夹或其子文件夹中的所有连接点。
来自网站:
介绍
Windows 2000 及更高版本支持目录符号链接,目录充当计算机上另一个目录的符号链接。例如,如果目录 D:\SYMLINK 指定 C:\WINNT\SYSTEM32 作为其目标,则访问 D:\SYMLINK\DRIVERS 的应用程序实际上将访问 C:\WINNT\SYSTEM32\DRIVERS。目录符号链接在 Windows 中称为 NTFS 连接点。遗憾的是,Windows 没有提供用于创建连接的工具 - 您必须购买 Win2K 资源工具包,它附带用于创建连接的 linkd 程序。因此,我决定编写自己的连接创建工具:Junction。Junction 不仅允许您创建 NTFS 连接点,还允许您查看文件或目录是否实际上是重新解析点。重新解析点是 NTFS 连接点所基于的机制,它们由 Windows 的远程存储服务 (RSS) 以及卷装入点使用。
请阅读此 Microsoft KB 文章以获取有关使用连接点的提示。
请注意,Windows 不支持远程共享上的目录连接。
如果要查看重新解析信息,Junction 的用法如下:
使用 Junction
使用 junction 列出连接点:
用法:[-s]
-s 递归子目录
例子:
要确定文件是否为连接点,请指定文件名:
连接点 c:\test
要列出目录下的连接点,请包含 –s 开关:
交界处-sc:\
要为“c:\Program Files”创建连接 c:\Program-Files:
C:\md 程序文件
C:> 连接 c:\Program-Files “c:\Program Files”
要删除连接点,请使用 –d 开关:
连接点-dc:\Program-Files
答案2
您不一定需要下载额外的程序来列出连接点、符号链接和硬链接,但如果您有特定的输出格式要求,它们可能会有所帮助。
列出当前目录及其子目录中的所有连接点、符号链接和符号链接目录:
dir /al /s
或者如果您希望它们单独列出...
列出当前目录及其子目录中的所有连接点:
dir /al /s | findstr "<JUNCTION>"
列出当前目录及其子目录中的所有符号链接:
dir /al /s | findstr "<SYMLINK>"
列出当前目录及其子目录中的所有符号链接目录:
dir /al /s | findstr "<SYMLINKD>"
属性标志l
在这里是关键;l
用于Reparse Points
(连接、符号链接和符号链接目录)
硬链接
不幸的是,dir
硬链接被列为普通文件,因此您无法使用它来识别硬链接。您可以改用内置功能fsutil
。它需要从提升的命令提示符运行。
使用fsutil
列出当前目录及其子目录中的所有硬链接:
for /F "usebackq tokens=2* delims=:" %G in (`forfiles /s /c "cmd /c fsutil hardlink list @path | findstr /n .* | findstr /b /v 1"`) do @fsutil hardlink list "%G" & echo.
这句话并不理想,我欢迎任何改进。
- 使用
forfiles
递归子目录选项(/s
)严重影响我的 CPU,并且需要一段时间才能完成。 - 基本上
fsutil
最终运行两次;第一次通过计算每次调用返回的输出行数来识别硬链接,第二次对刚刚找到的硬链接进行操作以获得正确的输出。 - 会有重复的行。要消除它们,您需要将输出重定向到文件,然后通过 之类的工具运行该文件
uniq
。
for
这是一个仅用于识别硬链接的批处理文件。由于forfiles
不涉及,它可能会稍微快一点,但它仍然受到上述单行程序的其余警告的影响。
@echo off
AT > NUL
if %ERRORLEVEL% NEQ 0 echo You need to run this script from an elevated command prompt. Exiting. && exit /B 1
for /R "%CD%" %%a IN (*.*) do (
for /F "usebackq tokens=2* delims=:" %%b in (`fsutil hardlink list "%%a" ^| findstr /n .* ^| findstr /b /v 1`) do (
fsutil hardlink list "%%b"
REM The following echo command breaks up each group of hard links with a blank line
echo.
)
)
还有一些其他(未经测试的)选项:
使用(旧)MicrosoftHL 扫描公用事业
hlscan /dir %CD%
使用替代方案寻找Microsoft 的 SFUA 实用工具包附带的命令:
find . -links +1
使用 Sysinternals 的查找链接fsutil
与上述类似
使用 Uwe Sieber 的列表链接程序 - 请参阅链接了解用法
使用 Nirsoft 的NTFS链接查看器如果你更喜欢 GUI 应用程序
答案3
从 Powershell 5+ 开始,以下单行代码以递归方式列出从以下位置开始的所有文件硬链接,目录连接和符号链接及其目标d:\Temp\
:
dir 'd:\Temp' -recurse -force | ?{$_.LinkType} | select FullName,LinkType,Target
输出:
FullName LinkType Target
-------- -------- ------
D:\Temp\MyJunctionDir Junction {D:\exp\junction_target_dir}
D:\Temp\MySymLinkDir SymbolicLink {D:\exp\symlink_target_dir}
D:\Temp\MyHardLinkFile.txt HardLink {D:\temp\MyHardLinkFile2.txt, D:\exp\hlink_target.xml}
D:\Temp\MyHardLinkFile2.txt HardLink {D:\temp\MyHardLinkFile.txt, D:\exp\hlink_target.xml}
D:\Temp\MySymLinkFile.txt SymbolicLink {..\exp\symlink_target.xml}
D:\Temp\MySymLinkDir\MySymLinkFile2.txt SymbolicLink {D:\temp\normal file.txt}
如果您关心硬链接的多个目标,请使用此变体,其中列出以制表符分隔的目标:
dir 'd:\Temp' -recurse -force | ?{$_.LinkType} | select FullName,LinkType,@{ Name="Targets"; Expression={$_.Target -join "`t"} }
您可能需要管理员权限才能运行该脚本C:\
。
要从传统命令行(cmd.exe)运行这些脚本:
PowerShell.exe -NoProfile -ExecutionPolicy Bypass -Command "<PowerShell commands>"
例如:
C:\>PowerShell.exe -NoProfile -ExecutionPolicy Bypass -Command "dir 'd:\Temp' -recurse -force | ?{ $_.LinkType } | select FullName, LinkType, @{ Name = \"Targets\"; Expression = { $_.Target -join \"`t\" } }"
2022 年 2 月更新:对于较新的 Windows 版本,您应该使用 Powershell v7.1 或更高版本。与 v5.1 相比,它有些精简,但在本例中它显示了正确的 LinkType。
答案4
硬链接最好如上所述进行描述,但对于符号链接和连接,以下内容可以很好地工作:
我在这里没有使用任何新命令,但是它通过向您显示在路径中找到的每个链接的列表、它的类型(SymLink / Junction)以及链接路径和目标路径,改进了一些列出的命令。
上面有一些不错的方法,但它们只给你目标路径,通常你想删除链接而不是目标,或者关联所有链接和目标。
要获取类型、链接和目标,您可以在 CMD 中使用以下命令:
FOR /F "Tokens=*" %A IN ('DIR /al /b /s G:\') DO @( for /F "Tokens=2,4 delims=<[]>" %B IN ('DIR /al "%~A"? ^| FIND /I " %~nA " ^| FIND /I "<" ^| FIND /I ">" ') DO @( ECHO.%~B: "%~A" → "%~C" ) )
示例输出:
SYMLINK: "G:\FTP\Root" → "G:\FTP\Data"
JUNCTION: "G:\FTP\Junctioned\BT\02" → "W:\FTPRoot\02"