Ale*_*lex 37 filesystems symlink
我在/home/user/system
包含标准 Linux 结构的路径中有一个完整的子文件系统,其中包含目录/bin
, /home
, /root
, /usr
, /var
, /etc
,...
这个子文件系统包含符号链接,无论是相对的还是绝对的。相对符号链接很好,它们保留在/home/user/system
. 但是绝对符号链接是有问题的,因为它们指向子文件系统之外的目标。
作为一个例子,我们假设一个绝对符号链接如下(在子文件系统中看到):
/usr/file1 -> /usr/lib/file1
Run Code Online (Sandbox Code Playgroud)
在整个文件系统中,我们现在有一个链接/home/user/system/usr/file1
指向/usr/lib/file1
子文件系统外部的文件,而不是子文件系统/home/user/system/usr/lib/file1
内部的文件。
我想要一个简单的脚本,最好是一个将每个绝对符号链接转换为相对符号链接的单个命令行(rsync、chroot、find 等)。
在给定的示例中,该相对链接将变为
/usr/file1 -> ../usr/lib/file1
Run Code Online (Sandbox Code Playgroud)
Gil*_*il' 24
使用Mark Lord的symlinks
实用程序(由许多发行版提供;如果您的发行版没有,请从源代码构建):
chroot /home/user/system symlinks -cr .
Run Code Online (Sandbox Code Playgroud)
或者,在具有readlink
命令和-lname
谓词的系统上find
(警告:未经测试的代码):
cd /home/user/system &&
find . -lname '/*' -exec ksh -c '
for link; do
target=$(readlink "$link")
link=${link#./}
root=${link//+([!\/])/..}; root=${root#/}; root=${root%..}
rm "$link"
ln -s "$root${target#/}" "$link"
done
' _ {} +
Run Code Online (Sandbox Code Playgroud)
小智 5
纯 bash 和 coreutils,将符号链接更改为相对../
路径,而路径中没有不必要的s:
find . -type l | while read l; do
target="$(realpath "$l")"
ln -fs "$(realpath --relative-to="$(dirname "$(realpath -s "$l")")" "$target")" "$l"
done
Run Code Online (Sandbox Code Playgroud)
你可以改变:
find .
到find /path/to/directory
到符号链接转换在该目录ln -fs
进行echo ln -fs
试运行解释:
target="$(realpath "$l")"
- 找到符号链接目标的绝对路径ln -fs
- 创建符号链接 ( -s
),强制 ( -f
) 重写现有realpath -s "$l"
- 找到符号链接本身的绝对路径dirname "$(realpath -s "$l")"
- 找到包含符号链接的目录的绝对路径realpath --relative-to="$(dirname "$(realpath -s "$l")")" "$target"
- 找到相对于符号链接的目标路径,换句话说:将绝对路径转换为相对路径