我可以使用什么幂等命令来创建指向目录的符号链接?

the*_*fog 20 shell-script symlink

我想将一个命令放入一个 shell 脚本中,该脚本将创建一个指向目录的符号链接,但该脚本可以一遍又一遍地运行,因此在后续调用中,该命令不应更改任何内容。

这是目录结构:

% tree /tmp/test_symlink 
/tmp/test_symlink
??? foo
??? repo
    ??? resources
        ??? snippets
            ??? php.snippets
            ??? sh.snippets
            ??? snippets.snippets
            ??? sql.snippets
            ??? vim.snippets
Run Code Online (Sandbox Code Playgroud)

我想在foo/指向目录的调用片段中创建一个符号链接/tmp/test_symlink/repo/resources/snippets
所以我运行:

% ln -sfv /tmp/test_symlink/repo/resources/snippets /tmp/test_symlink/foo/snippets
'/tmp/test_symlink/foo/snippets' -> '/tmp/test_symlink/repo/resources/snippets'
Run Code Online (Sandbox Code Playgroud)

这给出了预期的结果。

% tree /tmp/test_symlink                                                          
/tmp/test_symlink
??? foo
?   ??? snippets -> /tmp/test_symlink/repo/resources/snippets
??? repo
    ??? resources
        ??? snippets
            ??? php.snippets
            ??? sh.snippets
            ??? snippets.snippets
            ??? sql.snippets
            ??? vim.snippets
Run Code Online (Sandbox Code Playgroud)

5个目录,5个文件

但是,当再次运行该命令时,

% ln -sfv /tmp/test_symlink/repo/resources/snippets /tmp/test_symlink/foo/snippets
'/tmp/test_symlink/foo/snippets/snippets' -> '/tmp/test_symlink/repo/resources/snippets'
Run Code Online (Sandbox Code Playgroud)

它创建一个指向目录的符号链接,其中符号链接 aleady 存在将符号链接放在真实目录中

% tree /tmp/test_symlink                                                          
/tmp/test_symlink
??? foo
?   ??? snippets -> /tmp/test_symlink/repo/resources/snippets
??? repo
    ??? resources
        ??? snippets
            ??? php.snippets
            ??? sh.snippets
            ??? snippets -> /tmp/test_symlink/repo/resources/snippets
            ??? snippets.snippets
            ??? sql.snippets
            ??? vim.snippets
Run Code Online (Sandbox Code Playgroud)

为什么会发生这种情况,我该如何修改命令,以便后续调用不会产生这种奇怪的效果?

Ste*_*itt 21

您应该-T为此使用该选项,它告诉ln始终将链接名称视为所需的链接名称,而不是将其视为目录。

如果没有这个选项,如果你给出ln一个作为目录存在的链接名称,它会创建一个到该目录中目标的新链接。

请注意,这-T是一种 GNU 主义(至少,它不在 POSIX 中),但您已经在使用-v它也是一种 GNU 主义,所以我认为这不是问题。

或者,您可以将父目录指定为链接名称,并且链接将始终在那里(重新)创建:

ln -sfv /tmp/test_symlink/repo/resources/snippets /tmp/test_symlink/foo/
Run Code Online (Sandbox Code Playgroud)

这是有效的,因为您的符号链接与目标具有相同的名称。