如何自动将符号链接更改为busybox中的目录?


18

我正在尝试(尽可能接近)自动更改符号链接。我试过了:

ln -sf other_dir existing_symlink

这只是将新的符号链接放在现存的符号链接指向的目录中。

ln -sf other_dir new_symlink
mv -f new_symlink existing_symlink

那做同样的事情:将符号链接移到目录中。

cp -s other_dir existing_symlink

它拒绝,因为它是目录。

我已经读到它mv -T是为此做的,但是busybox没有该-T标志。

Answers:


1

我看不到如何获得原子操作。手册页symlink(2)说它给出EEXIST目标是否已经存在。如果内核不支持原子操作,那么您的用户空间限制就无关紧要。

mv -T即使您有帮助,我也看不出有什么帮助。在普通的Linux机器上尝试一下,将其与GNU mv一起使用:

$ mkdir a b
$ ln -s a z
$ mv -T b z
mv: cannot overwrite non-directory `z' with directory `b'

我认为您将必须分两步执行此操作:删除旧的符号链接并重新创建它。


1
确实,不幸的是您无法通过原子方式修改符号。最好的办法是删除旧链接并创建一个新链接。GNU coreutils可以选择使用单个命令(ln -snf)来执行此操作,但是在后台仍然有两个系统调用。
吉尔斯(Gilles)“所以,别再邪恶了”,2010年

43

的确可以用原子做rename(2),由下一个临时的名字第一次创建新的符号链接,然后干净利落地覆盖旧的符号链接一气呵成。如手册页所述:

如果newpath引用符号链接,则该链接将被覆盖。

在外壳程序中,您可以mv -T按照以下步骤进行操作:

$ mkdir a b
$ ln -s a z
$ ln -s b z.new
$ mv -T z.new z

您可以strace使用最后一条命令来确保它确实rename(2)在后台使用:

$ strace mv -T z.new z
lstat64("z.new", {st_mode=S_IFLNK|0777, st_size=1, ...}) = 0
lstat64("z", {st_mode=S_IFLNK|0777, st_size=1, ...}) = 0
rename("z.new", "z")                    = 0

请注意,以上mv -Tstrace都特定于Linux。

在FreeBSD上,mv -h交替使用。


1
非常好!最好在结尾处有一个从z到b的链接!
文森佐·皮

对于与操作系统无关的解决方案,请使用能够rename直接使用syscall而不是mv -hor 的脚本语言mv -T。例如,使用Perl:perl -e 'rename "z.new", "z" or die $!'
Slaven Rezic '18

8

拾起Arto在这里离开的地方,这是完全可能的,即使没有mv -T,您只需要创建一个与目标目录同名的新符号链接,并将其链接到目标mv的父目录中即可:

mkdir -p tmp/real_dir1 tmp/real_dir2
touch tmp/real_dir1/a tmp/real_dir2/a
# start with ./target_dir pointing to tmp/real_dir1
ln -s tmp/real_dir1 target_dir
# create a symlink named target_dir in tmp, pointing to real_dir2
ln -sf tmp/real_dir2 tmp/target_dir
# atomically mv it into ./ replacing ./target_dir
mv tmp/target_dir ./

通过(http://axialcorps.wordpress.com/2013/07/03/atomically-replacing-files-and-directories/)获取的代码示例


3

你试过了ln -snf吗?

-n当目标是指向目录的符号链接时,该选项将覆盖目标,而不是在目标下写入目标。

干杯


3
ln -snf不是原子的:它取消目标的链接,然后创建所需的符号链接。
吉尔斯(Gilles)'所以

2
鉴于OP希望“尽可能接近possib [e]”以原子方式更改符号链接,所以这是一个非常合理的答案。如果有更好的原子可以接近(或成为原子)原子,那么这个原子可以被接受。我认为没有必要投票。
威尔科,
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.