【问题标题】:Why does moving symlinked directory A to symlinked directory B cause A to be moved inside B?为什么将符号链接目录 A 移动到符号链接目录 B 会导致 A 在 B 中移动?
【发布时间】:2023-03-25 16:20:01
【问题描述】:

场景:我正在编写一个检查目录是否存在的 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就有了目标/Users/ysim/bar

【问题讨论】:

    标签: shell symlink overwrite mv ln


    【解决方案1】:

    之所以如此,是因为mv 要求操作系统进行移动,并且操作系统取消引用符号链接。要表现不同mv 需要额外的代码来检查符号链接和一些--dereference-target--dereference-src(或类似)选项。想想不同的用户可能会发现多少不同的行为。

    你需要

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

    顺便说一句,如果你想在一个脚本中

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

    【讨论】:

    • 啊,我明白了。因此,例如——如果我错了,请纠正我——不清楚你是想像我想做的那样将 A 的源移动到 B 的源 (~/.bam -> /Users/ysim/bar),还是 A 的目标到 B 的目标(~/.baz -> /Users/ysim/foo),或者让~/.bam 完全消失(仅~/.baz -> ~/bar)。
    • 不清楚 如果 mv 决定做任何超出 OS/libc 提供的事情。但是mv 没有,可能是因为就像你说的那样会有很多令人困惑的选择:)
    猜你喜欢
    • 1970-01-01
    • 2013-07-03
    • 2013-07-28
    • 1970-01-01
    • 2023-03-14
    • 2019-09-06
    • 2011-11-17
    • 1970-01-01
    • 2012-09-20
    相关资源
    最近更新 更多