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
选项将对beforeln
执行系统调用。下面,我的 linux 机器上的输出证明了这一点:unlink()
symlink()
strace
$ 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
所以我想最后的答案是“不”。
编辑:以下内容是从大约 2016 年在 unix.stackexchange.com 上的 Arto Bendiken 的回答中复制的。
这确实可以用 原子完成,rename(2)
首先在一个临时名称下创建新的符号链接,然后一次干净地覆盖旧的符号链接。正如手册页所述:
如果newpath引用符号链接,则该链接将被覆盖。
在 shell 中,您可以执行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 开始。请参阅此拉取请求。