2009-11-13 29 views
48

所以我创建了一个符号链接:有没有办法编辑一个符号链接而不先删除它?

ln -s /location/to/link linkname 

现在我想改变位置的符号链接的链接。我怎么做?有没有办法做到这一点,而不是先删除它?

+1

我想你会在这里得到更好的回应:http://serverfault.com/ – 2009-11-13 05:31:58

回答

26

您可以使用不同的名称创建新链接,然后将其移动以替换旧链接。

ln -s /location/to/link linkname 

后来

ln -s /location/to/link2 newlink 
mv newlink linkname 

如果newlinklinkname是同一个物理设备的mv应该是原子上。

+1

@Andrew - http://en.wikipedia.org/wiki/Atomic_operation – 2009-11-15 08:42:40

+0

仅供参考,我确定这可以在某些操作系统上运行,但这对我并不起作用,移动操作只是删除了“新”链接,而不是取代旧的。我仍然必须先听。 – pstanton 2013-07-07 23:21:36

+0

@pstanton你的意思是'mv newlink linkname'导致'newlink'文件被删除,但没有覆盖'linkname'文件?它是否默默地这样做?这似乎非常神秘。 – 2013-11-15 21:26:49

5

否如果新路径已存在,则symlink系统调用将返回EEXIST。您只能从文件系统中的新节点进行链接。这里有什么要求?如果您担心由于unlink/symlink调用的非原子性而导致竞争,那么您可能需要重新考虑该体系结构以便在别处提供同步。这种事情引发了一些可怕的安全漏洞。

19

尝试ln -sf new_destination linkname

+1

这是非原子的,但。详情请参阅我的回答。我不清楚这是否是海报的担忧。 – 2009-11-13 05:34:57

+10

这也不适用于指向目录的符号链接。它只会在旧的目标目录中创建一个新的符号链接。 – samxli 2011-07-28 09:26:08

+10

使用-n(--no-dereference)开关来解决这个问题。 – 2014-12-04 10:19:50

3

正如其他人所说的,您必须首先删除符号链接,无论是手动还是将-f标志传递给ln实用程序。

几年前,我不得不很频繁地对符号链接进行小的编辑,所以我编写了一个简单的基于readline的实用程序(edln),以减少烦人。如果其他人发现它很有用,我已经把它放在网上https://github.com/jjlin/edln/

edln将显示原始符号链接目标;然后可以使用箭头键或标准readline击键(M-bM-f,C-d等)四处移动并编辑目标。

4

链这样的命令:

rm currentlink && ln -s /path/to/link currentlink 

第一个命令删除现有的一个和所述第二立即再次创建它。

13

如果符号链接目标是目录,则需要将-T标志添加到mv命令中,否则它会将新符号链接移动到旧符号链接的目标目录中。

的原子交换一个网站,一个新的版本示例:

原始设置 - 网站存储在www1目录,虚拟主机指着www符号链接:

ln -s www1 www 

浏览网站,看到旧版本。

将新的网站文件放在新的www2目录中。

建立新的符号链接到新网站:

ln -s www_new www2 

移动www符号链接到新网站的目录:

mv -T www_new www 

浏览网站,马上看到新版本。

+0

显然,我NAS的微内核上的mv版本不支持-T参数。任何替代建议做这个原子? – OcularProgrammer 2014-03-27 23:16:00

+0

尝试使用-f(强制)标志创建符号链接。这似乎工作。请参阅下面的答案: 'ln -sf new_destination linkname' – 2014-03-27 23:46:10

6

在OSX,ln命令的手册页说,你可以做这样的

ln -shf /location/to/link link name 

从手册页:

The options are as follows: 
-F If the target file already exists and is a directory, then remove it so that the link may occur. The -F 
     option should be used with either -f or -i options. If none is specified, -f is implied. The -F option is 
     a no-op unless -s option is specified. 

-h If the target_file or target_dir is a symbolic link, do not follow it. This is most useful with the -f 
     option, to replace a symlink which may point to a directory. 

-f If the target file already exists, then unlink it so that the link may occur. (The -f option overrides any 
     previous -i options.) 

-i Cause ln to write a prompt to standard error if the target file exists. If the response from the standard 
     input begins with the character `y' or `Y', then unlink the target file so that the link may occur. Other- 
     wise, do not attempt the link. (The -i option overrides any previous -f options.) 

-n Same as -h, for compatibility with other ln implementations. 

-s Create a symbolic link. 

-v Cause ln to be verbose, showing files as they are processed. 
7

对于目录,你想要做: ln -sfT/location/to/new/target old_linkname

+0

这是一个好得多的解决方案,而不必调用第二个命令 – dsymquen 2014-07-07 14:16:51

0

只是google搜索,发现没有很好的答案,必须解决自己:

ln -f -s -T `readlink SomeLibrary | sed 's/version.old/version.new/'` SomeLibrary 

编辑的定义是指而不是从头开始重建,但部分地改变。任何需要记住路径的答案,可能很长或带有奇怪的符号,肯定是不好的。

6

只要改变链接目标:

# ln -sfT /path/to/new/target linkname

这是一个瞬间,原子变化。

相关问题