是否有任何操作系统提供一种机制(系统调用 - 而不是命令行程序)来更改符号链接(符号链接)引用的路径名 - 除了取消旧链接和创建新链接之外的路径名?
POSIX标准没有.Solaris 10没有.MacOS X 10.5(Leopard)没有.(我很可能确定AIX和HP-UX都没有.从这个Linux系统调用列表来看,Linux也没有这样的系统调用.)
有什么事吗?
(我期待答案是"不".)
由于证明负面是困难的,让我们重新组织这个问题.
如果您知道某些(类Unix)操作系统没有列出系统调用来重写符号链接的值(返回的字符串readlink()
)而不删除旧的符号链接并创建一个新的符号链接,请添加它 - 或者它们 -在答案中.
Taa*_*aai 158
是的你可以!
$ ln -sfn source_file_or_directory_name softlink_name
Run Code Online (Sandbox Code Playgroud)
Pas*_*ent 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
Run Code Online (Sandbox Code Playgroud)
编辑:正如OP在评论中指出的那样,使用该--force
选项将使之前ln
执行系统调用.下面,我的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
Run Code Online (Sandbox Code Playgroud)
所以我猜最后的答案是"不".
编辑:以下是从大约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
Run Code Online (Sandbox Code Playgroud)
您可以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
Run Code Online (Sandbox Code Playgroud)
需要注意的是在上面的,无论是mv -T
和strace
是Linux特有.
在FreeBSD上,mv -h
交替使用.
编者按:这就是卡皮斯特拉诺多年来一直在做的事情,从那时起〜2.15.请参阅此拉取请求.
mar*_*k4o 12
没有必要明确取消链接旧的符号链接.你可以这样做:
ln -s newtarget temp
mv temp mylink
Run Code Online (Sandbox Code Playgroud)
(或使用等效的符号链接并重命名调用).这比显式取消链接更好,因为重命名是原子的,因此可以确保链接始终指向旧目标或新目标.但是,这不会重用原始的inode.
在某些文件系统上,符号链接的目标存储在inode本身(代替阻止列表),如果它足够短; 这是在创建时确定的.
关于实际所有者和组是无关紧要的断言,Linux上的符号链接(7)表明存在重要的情况:
可以使用lchown(2)更改现有符号链接的所有者和组.符号链接的所有权唯一重要的时间是在具有粘滞位设置的目录中删除或重命名链接时(请参阅stat(2)).
可以使用utimensat(2)或lutimes(3)更改符号链接的最后访问和最后修改时间戳.
在Linux上,符号链接的权限不会在任何操作中使用; 权限始终为0777(所有用户类别的读取,写入和执行),并且无法更改.