删除perl脚本中的Windows符号链接?

时间:2012-03-01 18:26:37

标签: perl symlink

假设我创建了一些Windows符号链接,如:

rd /s /q source withlink linkdir
mkdir source
mkdir withlink
echo blah > source/myfile
cd withlink
touch blah
mklink mylink ..\source\myfile
@REM mklink /d linkdir ..\source
cd ..

我可以使用

删除shell中包含符号链接的目录
rd /s /q withlink

我在perl脚本中执行相同的任务,我们目前使用cygwin'rm -rf'。不幸的是我们正在使用cygwin 1.5并且rm和rm -rf在我想使用的符号链接(they delete symbolic link contents instead of the symlinks)上无法在该版本中正常工作。

如果我尝试:

use File::Path qw( rmtree ) ;
rmtree( ['withlink'] ) ;

这很好用,只要我没有任何目录符号链接(比如上面的create-the-links序列中的REM),那么perl的rmtree最终表现得像cygwin,我最终得到了我的原始目录的目录内容已删除。

是否有人建议我可以使用备用perl递归目录删除方法。我想到了一个shell标注:​​

system("rd /s /q withlink") ;

但这需要我测试平台并为Windows和Unix提供不同的perl代码。

编辑: 请注意,与Unix不同,unlink()不能删除目录符号链接,至少使用perl v5.6.0,这是我们的构建系统当前使用的。但是,rmdir()确实可以删除Windows目录符号链接。

2 个答案:

答案 0 :(得分:3)

您必须使用rmdir删除Windows中的目录符号链接和连接点,并且必须使用unlink来删除文件的符号链接。原因是目录符号链接和连接点实际上是一个空目录,带有其他文件系统元数据(称为重新分析点数据)。类似地,文件的符号链接是具有重新分析点数据的空文件。当您阅读Microsoft NTFS文档时,此类目录或文件称为重新分析点。重新分析点类型由所谓的重新分析点TAG 确定。用户可以看到两个重新分析点标记为“链接”:

  1. IO_REPARSE_TAG_SYMLINK - 如果在目录中设置 - 它是指向目录的符号链接,如果在文件中设置 - 它是文件的符号链接
  2. IO_REPARSE_TAG_MOUNT_POINT - 只能在目录上设置 - 它被称为“联结点”。它可以“链接”到另一个目录,但它可以是整个设备(卷)的“挂载点”。
  3. 总结:

    1. 将符号链接删除到目录和连接点,就好像它们是目录一样(事实上,如果你检查这样的事物的属性,它有两个:FILE_ATTRIBUTE_DIRECTORY和FILE_ATTRIBUTE_REPARSE_POINT)。
    2. 您可以将符号链接删除为文件,就像它们是文件一样。
    3. 在上述两种情况下 - 仅删除链接/结点(不是目标)。
    4. 要确定文件/文件夹是否为链接(所有类型):如果您致电GetFileAttributesGetFileInformationByHandleFindNextFile,则attributtes包含FILE_ATTRIBUTE_REPARSE_POINT标记(例如: WIN32_FIND_DATA::dwFileAttributes)。如果它是指向目录的链接,则它还包含标记FILE_ATTRIBUTE_DIRECTORY(请参阅 1。)。
    5. 希望有所帮助。

答案 1 :(得分:0)

您应该在perl脚本中使用unlink("FILE_FOO");调用。这是便携式的。