你可以改变什么符号链接指向创建后它?(Can you change what a symlink p

2019-07-19 04:05发布

是否任何操作系统提供一个机制(系统调用 - 而不是命令行程序)来更改由符号链接(符号链接)引用的路径 - 通过取消链接旧的,创造新的一个比其他?

POSIX标准没有。 的Solaris 10没有。 的MacOS X 10.5(Leopard)的没有。 (我还算某些既不AIX和HP-UX也无论是。从这份名单来看Linux系统调用 ,Linux没有这样的系统调用无论是。)

还有什么呢?

(我期待的答案是“否”。)


由于证明负是很难的,我们重组的问题。

如果你知道,不是已经列出了一些(类似Unix)操作系统没有系统调用重写一个符号链接的值(由返回的字符串readlink()而不删除旧的符号链接,并创建一个新的,请添加它-或者他们 - 在回答中。

Answer 1:

据我所知,没有,你不能。 你必须将其删除并重新创建它。 其实,你可以覆盖一个符号链接,从而更新由它引用的路径:

$ 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() 下面的输出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

所以我想最后的答案是“不”。

编辑 :从复制下面的阿尔托Bendiken的回答上unix.stackexchange.com过,大约2016年

这的确可以用自动完成的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 -Tstrace是Linux特有。

在FreeBSD,使用mv -h交替。

编者按:这是Capistrano的是如何做了好几年了,自从〜2.15如初。 见这个pull请求 。



Answer 2:

是的你可以!

$ ln -sfn source_file_or_directory_name softlink_name


Answer 3:

这是没有必要明确取消与旧符号链接。 你可以这样做:

ln -s newtarget temp
mv temp mylink

(或使用等效的符号链接,并重新命名调用)。 这是不是明确取消链接,因为重命名是原子的更好,所以你可以放心,该链接将始终指向无论是旧的或新的目标。 然而,这不会再使用原来的inode。

有些文件系统,符号链接的目标被存储在inode本身(把块列表),如果它足够短; 这是在创建它的时间来确定。

关于断言的实际所有者和组是无关紧要的, 符号链接(7)在Linux上说,存在这样的情况是显著的情况下:

现有的符号链接的所有者和组可使用lchown改变(2)。 当链接被删除或有粘性位设置的目录改名的符号链接的问题所有权是唯一的时间(请参阅stat(2))。

符号链接的上次访问和最后修改的时间戳可能使用utimensat(2)或lutimes被改变(3)。

在Linux上,一个符号链接的权限,任何操作都无法使用; 权限总是0777(读,写和执行所有的用户类别),并且不能更改。



Answer 4:

只是一个警告以上正确答案:

使用-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

这至少使我的文件。



Answer 5:

会不会取消链接,并在创建新的做同样的事情到底呢?



Answer 6:

万一它可以帮助:有编辑与午夜指挥官(MC)的符号连接的方式。 菜单命令(在法国我的MC接口上):

Fichier / Éditer le lien symbolique

其可以被转换为:

File / Edit symbolic link

该快捷方式是CX铯

也许它在内部使用ln --force命令,我不知道。

现在,我试图找到一种方式来编辑一大堆一次符号链接(这就是我来到这里)。



Answer 7:

从技术上讲,没有内置的命令编辑现有的符号链接。 它可以在短短的命令,可以轻松实现。

这是我写的更新现有的符号链接一点点的bash / zsh的功能

# -----------------------------------------
# Edit an existing symbolic link
#
# @1 = Name of symbolic link to edit
# @2 = Full destination path to update existing symlink with 
# -----------------------------------------
function edit-symlink () {
    if [ -z "$1" ]; then
        echo "Name of symbolic link you would like to edit:"
        read LINK
    else
        LINK="$1"
    fi
    LINKTMP="$LINK-tmp"
    if [ -z "$2" ]; then
        echo "Full destination path to update existing symlink with:"
        read DEST
    else
        DEST="$2"
    fi
    ln -s $DEST $LINKTMP
    rm $LINK
    mv $LINKTMP $LINK
    printf "Updated $LINK to point to new destination -> $DEST"
}


文章来源: Can you change what a symlink points to after it is created?
标签: unix symlink