我想将命令放入 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
命令的行为类似于cp
or mv
,即如果它在 <destination> 处看到一个“目录”,它将把文件放入其中,否则如果 <destination> 没有存在,它将生成 <destination>。 (这是“slashdot”技巧所避免的 - 即它将确保 <destination> 存在并且是一个目录)。
但我可能是错的。
无论哪种情况,这似乎都有效
ln -sfv --no-dereference /tmp/test_symlink/repo/resources/snippets/ foo/snippets