Unix 有没有办法编辑符号链接而不首先删除它?

Unix 有没有办法编辑符号链接而不首先删除它?,unix,symlink,Unix,Symlink,所以我创建了一个符号链接: ln -s /location/to/link linkname 现在我想更改符号链接链接到的位置。我该怎么做?有没有不先删除它的方法?没有。如果newpath已经存在,symlink系统调用将返回EEXIST。您只能从文件系统中的新节点进行链接。这里有什么要求?如果您担心由于unlink/symlink调用的非原子性而导致的竞争,那么您可能需要重新考虑一下体系结构,以便在其他地方提供同步。这类东西引入了一些可怕的安全漏洞。尝试ln-sf new\u destina

所以我创建了一个符号链接:

ln -s /location/to/link linkname

现在我想更改符号链接链接到的位置。我该怎么做?有没有不先删除它的方法?

没有。如果newpath已经存在,
symlink
系统调用将返回
EEXIST
。您只能从文件系统中的新节点进行链接。这里有什么要求?如果您担心由于unlink/symlink调用的非原子性而导致的竞争,那么您可能需要重新考虑一下体系结构,以便在其他地方提供同步。这类东西引入了一些可怕的安全漏洞。

尝试
ln-sf new\u destination linkname
您可以使用其他名称创建新链接,然后将其移动以替换旧链接

ln -s /location/to/link linkname
后来


如果
newlink
linkname
在同一个物理设备上,那么
mv
应该是原子的。

正如其他人所提到的,您基本上必须首先手动删除符号链接,或者将
-f
标志传递给
ln
实用程序

几年前,我不得不频繁地对符号链接进行小的编辑,所以我编写了一个简单的基于readline的实用程序(
edln
)来减少这种麻烦。如果其他人觉得它有用,我已经把它放在了网上


edln
将显示原始符号链接目标;然后,您可以使用箭头键或标准读线击键(
M-b
M-f
C-d
,等等)来移动和编辑目标。

像这样链接命令:

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

第一个命令删除现有的符号链接,第二个命令立即再次创建它。

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

以原子方式将网站切换到新版本的示例:

原始设置-网站存储在
www1
目录中,vhost指向
www
symlink:

ln -s www1 www
浏览至网站,查看旧版本

将新网站文件放入新的
www2
目录

设置新的符号链接到新网站:

ln -s www_new www2
mv -T www_new www
www
symlink移至新网站目录:

ln -s www_new www2
mv -T www_new www

浏览网站,立即查看新版本。

在OSX上,ln的手册页上说您可以这样做

ln -shf /location/to/link link name
从手册页:


对于目录,您要执行以下操作:
ln-sfT/location/to/new/target old_linkname

只是在谷歌上搜索,没有找到好的答案,不得不自己解决:

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

根据定义,编辑意味着不是从头开始重新创建,而是部分更改。任何需要记住路径的答案,可能很长或带有奇怪的符号,都是不好的。

只需更改符号链接目标:

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


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

我想你会得到更好的回答:这是非原子变化。有关详细信息,请参阅我的答案。我不清楚这是否是海报的问题。这也不适用于指向目录的符号链接。它只会在旧的目标目录中创建一个新的符号链接。请使用-n(--no-dereference)开关来解决此问题。@Andrew-FYI,我确信这在某些操作系统上有效,但对我来说不起作用,移动操作只是删除了“新”链接,而不是替换旧的链接。我还是必须先注册。@pstanton你是说
mv newlink linkname
导致
newlink
文件被删除,但没有覆盖
linkname
文件吗?它是默默地这样做的吗?这看起来非常神秘。
mv newlink linkname
会将您的
newlink
移动到
linkname
目录中。所以这个方法不是100%完美。@martinclayton@Urda Perhpas您应该使用
mv-T
而不是普通的
mv
?所以很明显,我的NAS微核上的mv版本不支持-T参数。有没有关于原子化的其他建议?尝试创建带有-f(force)标志的符号链接。这似乎奏效了。请参见下面的答案:
ln-sf new_destination linkname
这是一个比调用第二条命令更好的解决方案谢谢!我可以编译并运行它,但是makefile没有安装目标:-)请注意,至少在今天的bash中,您可以使用内置的readline支持:
read-e-p'New:'-i“$(readlink--“$1”)”lnk
将edln的一个版本实现为bash脚本会非常好,但是,readline行为似乎无法通过bash进行定制。我尝试了一下,但我还没有想出如何避免像shell转义文件名完成这样的不良行为。
(touch'ab';IFS=read-e-p'New:'-I./lnk;echo:$lnk:“;ls“$lnk”)
似乎对我有效,
read-e
撤销转义;在按下“用户必须删除”按钮后,只有一个尾随空格。。。键不是将
-r
传递到
读取
——及其所有含义。然后,制表符完成添加转义,这些转义由
read
的默认行为撤消
ln -f -s -T `readlink SomeLibrary | sed 's/version.old/version.new/'` SomeLibrary