有没有一种简单的方法可以将所有符号链接替换为它们链接到的文件?
有没有一种简单的方法可以将所有符号链接替换为它们链接到的文件?
Answers:
对于“简单”的一些定义:
#!/bin/sh
set -e
for link; do
test -h "$link" || continue
dir=$(dirname "$link")
reltarget=$(readlink "$link")
case $reltarget in
/*) abstarget=$reltarget;;
*) abstarget=$dir/$reltarget;;
esac
rm -fv "$link"
cp -afv "$abstarget" "$link" || {
# on failure, restore the symlink
rm -rfv "$link"
ln -sfv "$reltarget" "$link"
}
done
以链接名称作为参数运行此脚本,例如通过 find . -type l -exec /path/tos/script {} +
"$var"
为"${var}"
sh / bash中的noop。我删除了一个bashism([[
),其余的与POSIX sh兼容。
cp
,将同一个目录中的一个临时文件保存到同一目录中,然后mv -f
将该临时文件保存到原始目录中。这应该防止出现问题,例如人们Ctrl-C
在rm
和cp
命令之间停滞不前或文件系统被填满(从而甚至阻止了新文件ln
的工作)。临时文件名很容易发现,ls -a
以后可以根据需要进行清理。
abstarget=$(readlink -f "$link")
而不是case块了,但这可能是可移植性的原因。
仅使用tar将数据复制到新目录可能会更容易。
-H (c and r mode only) Symbolic links named on the command line will be followed; the target of the link will be archived, not the link itself.
你可以用这样的东西
tar -hcf - sourcedir | tar -xf - -C newdir
tar --help:
-H, --format=FORMAT create archive of the given format
-h, --dereference follow symlinks; archive and dump the files they point to
tar -hcf - sourcedir | tar -xf - -C newdir
cp -L
是更简单的解决方案
cp
实现都将复制目录。
如果我正确地理解了您的要求-L
,则该cp
命令的标志应该恰好满足您的要求。
只需复制所有符号链接,它将用它们指向的文件替换它们。
cp -L files tmp/ && rm files && cp tmp/files .
如果您弄清楚,您可能会帮助更多的人……
“轻松”很可能是您的功能。
我可能会编写一个脚本,该脚本使用“ find”命令行实用程序查找符号链接的文件,然后调用rm和cp来删除和替换该文件。您也可能做得很好,也可以通过find检查调用该动作,以确保在移动符号链接之前也有足够的可用空间。
另一个解决方案可能是通过隐藏符号链接的东西(如samba)挂载有问题的文件系统,然后从中复制所有内容。但是在许多情况下,类似的事情会带来其他问题。
您问题的更直接答案可能是“是”。
编辑:根据要求的更具体的信息。根据find的手册页,此命令将从/列出所有符号链接文件,深度为2个目录:
find / -maxdepth 2 -type l -print
(在这里找到)
要找到要执行的操作,请执行以下操作:
find / -maxdepth 2 -type l -exec ./ReplaceSymLink.sh {} \;
我相信它将调用我刚刚编写的一些脚本,并传递您刚刚找到的文件名。或者,您可以将查找输出捕获到文件中(使用“ find [blah]> symlinks.data”等),然后将该文件传递到您编写的脚本中,以优雅地处理原始文件的复制。
-exec ./ReplaceSymLink.sh {} \;
这是我使用的oneliner:假定所有本地文件都是“源”中另一个文件的链接。您可以使用模式或“查找”来优化文件选择。请在使用前了解。
对于*中的f; cp --remove-destination source / $ f $ f; 做完了
希望这可以帮助
那里有很多好的答案,但是我,因为您在寻找简单的东西
for i in *; do link=$(readlink $i) && rm $i && mv $link $i; done
find ./ -type l -print0|xargs -0 -n1 -i sh -c 'cp --remove-destination $(readlink "{}") "{}" '
基于MastroGeppetto的https://superuser.com/a/1301199/499386
for f in *; do cp --remove-destination $(readlink "$f") "$f"; done