【问题标题】:How to create symlink using Perl?如何使用 Perl 创建符号链接?
【发布时间】:2011-12-13 08:09:20
【问题描述】:

我正在尝试在 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 的新手。

【问题讨论】:

  • 谷歌搜索 windows symlink perl 会返回很多关于此的信息。简短的回答是,没有像 Windows 中的 *nix 那样的“符号链接”这样的东西。 perl 文档告诉您,如果底层操作系统不支持符号链接,symlink 将失败。
  • @Brian Roach 当然有......好吧,在过去 5 年发布的 Windows 版本中;-)
  • @pst - 注意“like there is in *nix”这句话。他们……不一样。你会认为 activestate 会做一些事情而不仅仅是失败,但他们不会。
  • @pst - 这在 perl 中不可用;这是一个系统命令。添加您需要以提升的权限运行才能创建 NTFS 符号链接的事实,我将坚持“不一样”
  • @BrianRoach Junctions(目录符号链接)至少可以在不需要提升权限的情况下创建。

标签: perl symlink


【解决方案1】:

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

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

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

编码愉快。


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


FWIW,这在 Strawberry 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 存在吗? 1
lnk.txt 存在吗?
结果:
lnk.txt 存在吗? 1
关联数据:hello world!

目录列表:

2011 年 10 月 22 日下午 02:53  。
2011 年 10 月 22 日下午 2:53  ..
2011 年 10 月 22 日下午 2:54 636 foo.pl
10/22/2011 02:53 PM  lnk.txt [src.txt]
10/22/2011 02:53 PM 14 src.txt

我不知道 NTFS 符号链接和“UNIX”符号链接之间可能存在什么 [细微的] 差异(如果有的话)。此外,上述 不会工作 pre-Vista/2008 -- NTFS 的早期版本 支持符号链接(并且 Windows 的早期版本没有 @987654330 @函数)。

【讨论】:

  • 种类:NTFS 符号链接。我以管理员身份登录,并且 cmd 提示在其标题中确实说管理员。如何在 perl 脚本中运行 mklink?
  • 您的代码运行良好。但是当我尝试融入我的内部时,什么也没有发生。 code 使用 Win32::API; $fn = Win32::API->new( # Note "A" function, IDK how to use Unicdoe "kernel32", "BOOLEAN CreateSymbolicLinkA(LPTSTR lpSymlinkFileName, LPTSTR lpTargetFileName, DWORD flags)" ); $hr = $fn->调用($oldname, $newname, 0); code
  • @Red "什么都没发生" 还是...?
  • 我添加了 print:code $hr = $fn->Call($oldname, $newname, 0) or die print "$!\n"; code 现在进入控制台:1 在 C:\...\CreateSymlink.pl 第 20 行。
  • @Red 请记住,windows 调用 [通常] 在“成功”时返回 0 的“结果”(似乎映射到 undef ???......无论如何它都是假的)。确保路径(相对/绝对)正确并记住传递“目录”标志以链接目录。这是一个 Windows 调用,因此它使用 Windows 路径规则。不知道该说什么:)
【解决方案2】:

解决方法:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-06-06
    • 2019-04-18
    • 2013-07-29
    • 1970-01-01
    • 1970-01-01
    • 2021-12-19
    相关资源
    最近更新 更多