Answers:
这可的确可以用原子做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 -T
和strace
都特定于Linux。
在FreeBSD上,mv -h
交替使用。
rename
直接使用syscall而不是mv -h
or 的脚本语言mv -T
。例如,使用Perl:perl -e 'rename "z.new", "z" or die $!'
拾起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/)获取的代码示例
你试过了ln -snf
吗?
-n
当目标是指向目录的符号链接时,该选项将覆盖目标,而不是在目标下写入目标。
干杯
ln -snf
不是原子的:它取消目标的链接,然后创建所需的符号链接。
ln -snf
)来执行此操作,但是在后台仍然有两个系统调用。