AFAIK,不,您不能。您必须将其删除并重新创建。实际上,您可以覆盖符号链接,从而更新其引用的路径名:
$ ln -s .bashrc test
$ ls -al test
lrwxrwxrwx 1 pascal pascal 7 2009-09-23 17:12 test -> .bashrc
$ ln -s .profile test
ln: creating symbolic link `test': File exists
$ ln -s -f .profile test
$ ls -al test
lrwxrwxrwx 1 pascal pascal 8 2009-09-23 17:12 test -> .profile
编辑:正如OP在注释中指出的那样,使用该--force
选项将使ln
对unlink()
before 的系统调用symlink()
。下面,strace
在我的linux盒子上的输出证明了这一点:
$ strace -o /tmp/output.txt ln -s -f .bash_aliases test
$ grep -C3 ^unlink /tmp/output.txt
lstat64("test", {st_mode=S_IFLNK|0777, st_size=7, ...}) = 0
stat64(".bash_aliases", {st_mode=S_IFREG|0644, st_size=2043, ...}) = 0
symlink(".bash_aliases", "test") = -1 EEXIST (File exists)
unlink("test") = 0
symlink(".bash_aliases", "test") = 0
close(0) = 0
close(1) = 0
因此,我想最后的答案是“否”。
编辑:以下是从Arto Bendiken的答案复制过来的,大约在2016年unix.stackexchange.com上。
这可的确可以用原子做rename(2)
,由下一个临时的名字第一次创建新的符号链接,然后干净利落地覆盖旧的符号链接一气呵成。如手册页所述:
如果newpath引用符号链接,则该链接将被覆盖。
在外壳程序中,您可以mv -T
按照以下步骤进行操作:
$ mkdir a b
$ ln -s a z
$ ln -s b z.new
$ mv -T z.new z
您可以strace
使用最后一条命令来确保它确实rename(2)
在后台使用:
$ strace mv -T z.new z
lstat64("z.new", {st_mode=S_IFLNK|0777, st_size=1, ...}) = 0
lstat64("z", {st_mode=S_IFLNK|0777, st_size=1, ...}) = 0
rename("z.new", "z") = 0
请注意,以上mv -T
和strace
都特定于Linux。
在FreeBSD上,mv -h
交替使用。
编者注:这就是Capistrano从〜2.15开始多年来所做的。请参阅此拉取请求。
ln
覆盖旧链接的命令(或等效于API)?你有什么问题