如何使用Perl创建符号链接?

时间:2011-10-22 21:06:57

标签: perl symlink

我试图在Perl中运行以下代码:

symlink($oldname,$newname) or die print "$!\n";

但我收到错误说:

The symlink function is unimplemented at C:\...\CreateSymlink.pl line 14.

如果我将代码更改为:

link($oldname,$newname) or die print "$!\n";

然后正在创建没有错误的硬链接。

使用Activestate Perl和Windows 7 32位。

为什么会发生这种情况?我正在尝试为文件创建符号链接。

P.S:我是Perl的新手。

2 个答案:

答案 0 :(得分:9)

哪种“符号链接”? ; - )

哦,阅读上面关于mklink命令的维基百科文章的符号链接;-) Back-ticks (or system)可以成为好朋友,但请注意:

  

Windows Vista / Windows 7中的默认安全设置禁止非提升管理员和所有非管理员创建符号链接。可以[通过安全策略设置]更改此行为...

快乐的编码。


WinAPI CreateSymbolicLink函数可以直接使用;我不确定它是否“受到”与上面mklink命令相同的限制。但是,this thread表示它仍然有效。


FWIW,这在“草莓Perl 5.12”中起作用。 YMMV,我刚打了这个,但从来没有用过它: - )

use Win32::API;
$fn = Win32::API->new(
    # Note "A" function, IDK how to use Unicdoe
    "kernel32", "BOOLEAN CreateSymbolicLinkA(LPTSTR lpSymlinkFileName, LPTSTR lpTargetFileName, DWORD flags)"
);

unlink("src.txt");
unlink("lnk.txt");
open(FH,">src.txt") or die $!;
close(FH);

print "src.txt exists? " , (-f "src.txt"), "\n";
print "lnk.txt exists? " , (-f "lnk.txt"), "\n";
$hr = $fn->Call("lnk.txt", "src.txt", 0);
print "Result: ", $hr, "\n";
print "lnk.txt exists? ", (-f "lnk.txt"), "\n";

open(FH,">>src.txt") or die $!;
print FH "hello world!\n";
close(FH);

open(FH,"<lnk.txt") or die $!;
print "linked data: ", scalar(<FH>), "\n";
close(FH);

我的结果(以“管理员”身份运行 - 可能不适用于“其他用户” - 我不知道为什么但我的cmd.exe始终以提升的权限打开):

src.txt exists? 1
lnk.txt exists?
Result:
lnk.txt exists? 1
linked data: hello world!

目录列表:

10/22/2011  02:53 PM    <DIR>          .
10/22/2011  02:53 PM    <DIR>          ..
10/22/2011  02:54 PM               636 foo.pl
10/22/2011  02:53 PM    <SYMLINK>      lnk.txt [src.txt]
10/22/2011  02:53 PM                14 src.txt

我不知道NTFS符号链接和“UNIX”符号链接之间可能存在的[微妙]差异(如果有的话)。此外,上面的将无法正常运行 Vista-2008之前 - 以前版本的NTFS 不支持支持符号链接(以前版本的Windows没有{{ 1}}功能)。

答案 1 :(得分:1)

制定了解决方法:

my $oldfilename = File::Spec->catfile($oldname);
my $newfilename = File::Spec->catfile($newname);
if(-f $newfilename){ } else {
    @args = ("mklink", $newfilename, $oldfilename);
    system(@args) == 0; }