如何复制相对符号链接并保留目标

tdi*_*ihp 5 linux symbolic-link

我的情况有 2 个目录:/blah/d01 和 /blah/d02

$ls -l /blah/d01
a/
b/
c/
fa -> a
fb -> b
fc -> c
Run Code Online (Sandbox Code Playgroud)

我想将 fa、fb、fc 复制到 /blah/d02,结果:

$ls -l /blah/d02
fa -> ../d01/a
fb -> ../d01/b
fc -> ../d01/c
Run Code Online (Sandbox Code Playgroud)

关键是,我想做一些像 cp --{some magic attr} /blah/d01/f* /blah/d02/ 这样的事情来实现这一点。

谢谢

更新

我解决了一个 bash 脚本:

#! /bin/bash
for i in $@; do echo $i && [ -L $i ] && ln -s $(dirname $i)/$(readlink $i) $(basename $i); done
Run Code Online (Sandbox Code Playgroud)

基于旧链接创建新链接(确保它们使用相对路径)

再次更新

我发现我的最后一个脚本有效,但是在将符号链接从 a 复制到 b 和从 b 复制到 c 后,链接路径会很长(充满奇怪的相对路径),所以我添加了一些东西来清理相对路径,脚本结束:

#! /bin/bash
function relpath {
  source=$1
  target=$2

  common_part=$source
  back=
  while [ "${target#$common_part}" = "${target}" ]; do
    common_part=$(dirname $common_part)
    back="../${back}"
  done

  echo ${back}${target#$common_part/}
}

for i in $@; do echo $i && [ -L $i ] && ln -s $(relpath $PWD $(readlink -f $i)); done
Run Code Online (Sandbox Code Playgroud)

Izz*_*zzy 1

由于这些符号链接是在没有完全限定路径的情况下创建的,因此使用cp. 但你可以在目标处创建新的:

for i in *; do [ -L $i ] && cd blah && ln -s ../$i $i && cd -; done
Run Code Online (Sandbox Code Playgroud)

简短说明:

  • for i in *:循环当前位置的文件/目录列表
  • do: 封装必须要做的事情
  • [ -L $i ] &&: 仅当当前条目是符号链接时才继续
  • cd blah && ln -s ../$i $i && cd -:更改为 blah 并创建到原始位置的符号链接

这还不是您想要的(因为它对符号链接进行了符号链接)。所以我们稍微修改一下:

for i in *; do [ -L $i ] && cd blah && ln -s ../$(readlink ../$i) $i && cd -; done
Run Code Online (Sandbox Code Playgroud)

添加的构造$(readlink ../$i)评估链接指向的对象,并将结果放在那里。瞧——结果就是您想要的。

请注意,我稍微简化了您的请求(使您只是想将符号链接复制到子目录),因此更容易遵循。您必须调整它,因为我不认为您的真实目录被调用blah:)