为什么将符号链接目录A移动到符号链接目录B导致A在B内移动?

时间:2013-09-12 01:55:45

标签: shell symlink overwrite mv ln

场景:我正在编写一个shell脚本来检查目录是否存在;如果是,它是一个符号链接,它会重命名目录名后附加.bak的目录。但是,我注意到,如果我将符号链接目录(目录A)移动到另一个符号链接目录(B),则会导致A在 B内移动,而不是覆盖B.

举例说明:

$ mkdir foo                                                                     
$ mkdir bar                                                                     
$ ln -s "$PWD/foo" ~/.baz                                                       
$ ls -al ~/.baz                                                                 
lrwxr-xr-x  1 ysim  staff  15 Sep 11 21:45 /Users/ysim/.baz -> /Users/ysim/foo  
$ mv ~/.baz ~/.bam                                                              
$ ls -al ~/.bam                                                                 
lrwxr-xr-x  1 ysim  staff  15 Sep 11 21:45 /Users/ysim/.bam -> /Users/ysim/foo  
$ ls -al ~/.baz                                                                 
ls: /Users/ysim/.baz: No such file or directory                                                                                                   
$ ln -s "$PWD/bar" ~/.baz                                                       
$ ls -al ~/.baz                                                                 
lrwxr-xr-x  1 ysim  staff  15 Sep 11 21:47 /Users/ysim/.baz -> /Users/ysim/bar  
$ ls -al ~/.bam                                                                 
lrwxr-xr-x  1 ysim  staff  15 Sep 11 21:45 /Users/ysim/.bam -> /Users/ysim/foo  

现在,当我重命名/移动~/.baz~/.bam时:

$ mv ~/.baz ~/.bam                 

~/.baz/Users/ysim/bar)的目标未按预期移至~/.bam的目标:

$ ls -al ~/.bam                                                                 
lrwxr-xr-x  1 ysim  staff  15 Sep 11 21:45 /Users/ysim/.bam -> /Users/ysim/foo 

相反,整个~/.baz符号链接已移动到里面 ~/.bam目录:

$ ls -al ~/.bam/
total 8
drwxr-xr-x   3 ysim  staff   102 Sep 11 21:47 .
drwxr-xr-x+ 96 ysim  staff  3264 Sep 11 21:51 ..
lrwxr-xr-x   1 ysim  staff    15 Sep 11 21:47 .baz -> /Users/ysim/bar

为什么?我如何去做我打算做的事情,即将~/.baz的目标写入~/.bam的目标,以便~/.bam具有目的地{{1} }?

1 个答案:

答案 0 :(得分:1)

它的工作方式与此类似,因为mv要求操作系统执行移动操作,操作系统取消引用符号链接。要采取不同的行为mv,需要额外的代码来检查符号链接和一些--dereference-target--dereference-src(或类似)选项。想想不同用户可能会发现的不同行为的数量。

你需要

rm "$dest"
cp -a "$src" "$dest"
# in your case src=".bam" and dest=".baz"

BTW,如果你想要

的脚本
  • “读取”脚本中符号链接的目标:target=$(readlink "$f")
  • 测试文件是否为符号链接:test -l "$f"