Perl - 检测Windows 10下的符号链接

时间:2018-05-09 00:52:27

标签: perl windows-10

我在检测Windows 10下支持它们的符号链接时遇到问题。首先我尝试了这个:

if(! -l $import_filename) {
    print "$0: $import_filename is not a symlink";
}

这不起作用。当$ import_filename是符号链接时,它会被执行。然后我尝试了这个:

use File::stat;
use Fcntl;

my $statbuf = lstat($import_filename);
if(!($statbuf->mode & S_ISLNK)) {
    print "$0: $import_filename is not a symlink";
}

这似乎是一种不同的方式来说同样的事情。正如所料,在具有符号链接/联结支持的Windows版本下,有没有任何有福的方法可以做到这一点?如果没有,命令行工具也是可接受的答案。

2 个答案:

答案 0 :(得分:2)

鉴于

>mklink file_symlink file
symbolic link created for file_symlink <<===>> file

>mklink /d dir_symlink dir
symbolic link created for dir_symlink <<===>> dir

>mklink /h file_hardlink file
Hardlink created for file_hardlink <<===>> file

>mklink /j dir_hardlink dir
Junction created for dir_hardlink <<===>> dir

>dir
...
2018-05-09  12:59 AM    <JUNCTION>     dir_hardlink [C:\...\dir]
2018-05-09  12:58 AM    <SYMLINKD>     dir_symlink [dir]
2018-05-09  12:56 AM                 6 file_hardlink
2018-05-09  12:58 AM    <SYMLINK>      file_symlink [file]
...

您可以使用以下内容检测file_symlinkdir_symlinkdir_hardlink(但不是file_hardlink)作为链接:

use Win32API::File qw( GetFileAttributes FILE_ATTRIBUTE_REPARSE_POINT );

my $is_link = GetFileAttributes($qfn) & FILE_ATTRIBUTE_REPARSE_POINT;

我不知道如何区分硬链接和符号链接(尽管可以使用& FILE_ATTRIBUTE_DIRECTORY来区分文件和目录)。

答案 1 :(得分:0)

似乎没有太多的Perl支持在Windows上使用符号链接(如果有的话)。根据{{​​3}}页面perlportfor symlink,并未实现任何相关内置函数。

最重要的是,对于您的直接问题for readlink,要么就是没有符号链接的文件测试。 lstat isn't implemented表示

  

-g-k-l-u-A不是特别有意义。

除了使用Windows API之外,我还没有在CPAN上找到任何内容。

然后您可以转到Windows命令行,在<SYMLINK>输出中查找dir

# Build $basename and $path from $import_filename if needed
if ( not grep { /<SYMLINK>.*$basename/ } qx(dir $path) ) {
    say "$0: $import_filename is not a symlink";
}

需要使用$basename,因为dir没有显示路径。例如,使用核心模块perlport for -X

可以获得具有完整路径的文件名的组件
use File::Spec;
my ($vol, $path, $basename) = File::Spec->splitpath($import_filename);

如果文件名没有路径,那么$vol$path是空字符串,这对于dir是可以的,因为它不需要当前目录的参数。如果设计$import_filename引用当前目录(没有路径),则在正则表达式中使用qx(dir)(无参数)。

dir输出也会显示目标名称,可以派上用场。