是否有任何操作系统提供一种机制(系统调用 - 而不是命令行程序)来更改符号链接(符号链接)引用的路径名 - 除了取消旧链接和创建新链接之外的其他路径名?
POSIX标准没有。 Solaris 10没有。 MacOS X 10.5(Leopard)没有。 (我很可能确定AIX和HP-UX都没有。从这个Linux system calls列表来看,Linux也没有这样的系统调用。)
有什么用吗?
(我希望答案是“不”。)
由于证明消极是很难的,让我们重新组织这个问题。
如果您知道某些(类Unix)操作系统尚未列出系统调用,无需删除旧符号链接并创建新符号链接来重写符号链接的值(readlink()
返回的字符串) ,请在答案中添加它 - 或者它们。
答案 0 :(得分:153)
是的,你可以!
$ ln -sfn source_file_or_directory_name softlink_name
答案 1 :(得分:100)
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()
之前执行系统调用symlink()
}}。下面,我的linux盒子上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
所以我猜最后的答案是“不”。
编辑:以下内容从Arto Bendiken's answer复制到unix.stackexchange.com,大约2016年。
这个可以确实以rename(2)
原子方式完成,首先在临时名称下创建新的符号链接,然后一次性干净地覆盖旧的符号链接。正如man page所述:
如果 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。请参阅this pull request。
答案 2 :(得分:12)
没有必要明确取消链接旧的符号链接。你可以这样做:
ln -s newtarget temp
mv temp mylink
(或使用等效的符号链接并重命名调用)。这比显式取消链接更好,因为重命名是原子的,因此可以确保链接始终指向旧目标或新目标。但是,这不会重用原始的inode。
在某些文件系统上,符号链接的目标存储在inode本身(代替阻止列表),如果它足够短;这是在创建时确定的。
关于实际所有者和组无关紧要的断言,Linux上的symlink(7)表示有一个重要的案例:
可以使用更改现有符号链接的所有者和组 lchown(2)。唯一一个符号链接的所有权重要的是 在具有粘性的目录中删除或重命名链接时 位设置(见stat(2))。
符号链接的最后一次访问和最后修改时间戳可以是 使用utimensat(2)或lutimes(3)更改。
在Linux上,符号链接的权限不会在任何操作中使用; 权限始终为0777(所有用户的读取,写入和执行) 类别),并且不能改变。
答案 3 :(得分:2)
只是警告上面的正确答案:
如果混淆源和目标,使用-f / --force方法可能会丢失文件:
mbucher@server2:~/test$ ls -la
total 11448
drwxr-xr-x 2 mbucher www-data 4096 May 25 15:27 .
drwxr-xr-x 18 mbucher www-data 4096 May 25 15:13 ..
-rw-r--r-- 1 mbucher www-data 4109466 May 25 15:26 data.tar.gz
-rw-r--r-- 1 mbucher www-data 7582480 May 25 15:27 otherdata.tar.gz
lrwxrwxrwx 1 mbucher www-data 11 May 25 15:26 thesymlink -> data.tar.gz
mbucher@server2:~/test$
mbucher@server2:~/test$ ln -s -f thesymlink otherdata.tar.gz
mbucher@server2:~/test$
mbucher@server2:~/test$ ls -la
total 4028
drwxr-xr-x 2 mbucher www-data 4096 May 25 15:28 .
drwxr-xr-x 18 mbucher www-data 4096 May 25 15:13 ..
-rw-r--r-- 1 mbucher www-data 4109466 May 25 15:26 data.tar.gz
lrwxrwxrwx 1 mbucher www-data 10 May 25 15:28 otherdata.tar.gz -> thesymlink
lrwxrwxrwx 1 mbucher www-data 11 May 25 15:26 thesymlink -> data.tar.gz
当然这是有意的,但通常会出现错误。因此,删除和重建符号链接是一项更多的工作,但也有点节省:
mbucher@server2:~/test$ rm thesymlink && ln -s thesymlink otherdata.tar.gz
ln: creating symbolic link `otherdata.tar.gz': File exists
至少保留我的文件。
答案 4 :(得分:1)
不会取消链接并创建新版本最终会做同样的事情吗?
答案 5 :(得分:0)
以防它有所帮助:有一种方法可以使用午夜指挥官(mc)编辑符号链接。 菜单命令是(我的mc界面上的法语):
Fichier / Éditer le lien symbolique
可以翻译为:
File / Edit symbolic link
快捷方式是C-x C-s
也许它在内部使用ln --force
命令,我不知道。
现在,我正试图找到一种方法来同时编辑大量的符号链接(这就是我到达这里的方式)。