我在检测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版本下,有没有任何有福的方法可以做到这一点?如果没有,命令行工具也是可接受的答案。
答案 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_symlink
,dir_symlink
和dir_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}}页面perlport和for 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
输出也会显示目标名称,可以派上用场。