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

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

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

这是目录结构:

% tree /tmp/test_symlink 
/tmp/test_symlink
├── foo
└── repo
    └── resources
        └── snippets
            ├── php.snippets
            ├── sh.snippets
            ├── snippets.snippets
            ├── sql.snippets
            └── vim.snippets

我想在foo/名为 snippets 中创建一个指向该目录的符号链接/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'

这给出了所需的结果。

% 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

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'

它创建一个到目录的符号链接,其中符号链接已经存在,将符号链接放入真实目录中

% 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

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

答案1

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

如果没有此选项,如果您给出ln作为目录存在的链接名称,它将创建一个指向该目录内目标的新链接。

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

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

ln -sfv /tmp/test_symlink/repo/resources/snippets /tmp/test_symlink/foo/

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

答案2

我能说的最好的情况是,在第二遍时,ln命令的行为类似于cpor mv,即如果它在 <destination> 处看到一个“目录”,它将把文件放入其中,否则如果 <destination> 没有存在,它将生成 <destination>。 (这是“slashdot”技巧所避免的 - 即它将确保 <destination> 存在并且是一个目录)。
但我可能是错的。

无论哪种情况,这似乎都有效

ln -sfv --no-dereference /tmp/test_symlink/repo/resources/snippets/ foo/snippets

相关内容