perl 中的 symlink 函数是否会覆盖现有的 link

Does symlink function in perl overwrite an existing link

我正在尝试模仿 Unix 命令

ln -sf /path/to/file /path/to/link

通过使用 Perl

symlink (/path/to/file /path/to/link) 

Perl 是否删除现有目标文件并创建类似于 -s -f 选项的符号链接?

这个很简单,自己想办法。让我们试穿

ls -li link_to_FILE.txt
# 2415940160 lrwxrwxrwx.  ...  link_to_FILE.txt -> FILE.txt

perl -wE'symlink "FILE.txt", "link_to_FILE.txt" or warn "Cant make it: $!"'

它打印

Cant make it: File exists at -e line 1.

并且我检查了具有相同 inode 编号的原始文件 (link) 是否仍然存在。

所以,不,它不会覆盖现有文件。

symlink 的页面表明没有 f 的选项。

symlink 只是用相同的名称 (symlink(2)) 调用 OS 调用,当“newpath 时 returns 错误 EEXIST已经存在。

如果你想实现-f,你可以使用

unlink($new_qfn);
symlink($old_qfn, $new_qfn)
   or die("Can't create symlink \"$new_qfn\": $!\n");

但是,下面的代码在处理竞争条件方面做得更好:

if (!symlink($old_qfn, $new_qfn)) {
   if ($!{EEXIST}) {
      unlink($new_qfn)
         or die("Can't remove \"$new_qfn\": $!\n");
      symlink($old_qfn, $new_qfn)
         or die("Can't create symlink \"$new_qfn\": $!\n");
   } else {
      die("Can't create symlink \"$new_qfn\": $!\n");
   }
}

ln 使用后一种方法。

$ strace ln -sf a b
...
symlink("a", "b")                       = -1 EEXIST (File exists)
unlink("b")                             = 0
symlink("a", "b")                       = 0
...