跳转至

ln 避免软链一个已存在的目录

在使用 ln -sf source target 进行目录软链时,如果目标连接存在,那么可能出现再链接一个子目录的情况。

示例

对于这样一个目录结构

$ ls
source
target -> ./source

当我想再次重新进行软链接时

ln -svf source target

期望的效果

$ ls
source
target -> ./source

实际效果

$ ls
source
target/source -> ./source

原因

这是因为 ln 命令将 target 当作一个文件夹对待,而通常情况下,当 target 为文件夹时,ln 会在文件夹下创建一个和 source 同名的软链,例如以下情况

$ ls
source
target

ln -svf source target

$ls
source
target/source -> ./source

所以需要告诉 ln 命令,如果 target 是软链且是目录,那么将他当作一个普通文件对待。

查看 ln 的帮助文档

$ ln --help
-b                          like --backup but does not accept an argument
-d, -F, --directory         allow the superuser to attempt to hard link
                              directories (note: will probably fail due to
                              system restrictions, even for the superuser)
-f, --force                 remove existing destination files
-i, --interactive           prompt whether to remove destinations
-L, --logical               dereference TARGETs that are symbolic links
-n, --no-dereference        treat LINK_NAME as a normal file if
                              it is a symbolic link to a directory
-P, --physical              make hard links directly to symbolic links
-r, --relative              create symbolic links relative to link location
-s, --symbolic              make symbolic links instead of hard links
-S, --suffix=SUFFIX         override the usual backup suffix
-t, --target-directory=DIRECTORY  specify the DIRECTORY in which to create
                              the links
-T, --no-target-directory   treat LINK_NAME as a normal file always
-v, --verbose               print name of each linked file
    --help     display this help and exit
    --version  output version information and exit

可以看到 -n -T 都有这样功能。区别在于使用 -T 时始终将 target 作为普通文件,一旦 target 不是软链接而是常规目录时,会报错。而 -n 在这种情况下会将 target 当作一个目录,在其目录下建立一个和 source 同名的软链。视情况使用。

ln -svfn source target
ln -svfT source target