it-swarm.cn

如何“重新链接”很多断开的符号链接?

我有一个目录树,其中有一堆符号链接到/home下的文件...但是,我已将/home移到/mnt/home,并且需要一种方法来“重新链接”所有符号链接。是否存在这样的功能,或者我需要编写脚本来做到这一点?

例如,我有如下内容:

[[email protected] ~]# ls -l /mnt/home/someone/something
total 4264
lrwxrwxrwx 1 jnet www-data      55 2011-08-07 13:50 a -> /home/someone/someotherthing/a
lrwxrwxrwx 1 jnet www-data      55 2011-08-07 13:50 b -> /home/someone/someotherthing/b
lrwxrwxrwx 1 jnet www-data      55 2011-08-07 13:50 c -> /home/someone/someotherthing/c
lrwxrwxrwx 1 jnet www-data      55 2011-08-07 13:50 d -> /home/someone/someotherthing/d
lrwxrwxrwx 1 jnet www-data      55 2011-08-07 13:50 e -> /home/someone/someotherthing/e

/mnt/home/someone/something/subdir:
total 4264
lrwxrwxrwx 1 jnet www-data      55 2011-08-07 13:50 a -> /home/someone/someotherthing/subdir/a
lrwxrwxrwx 1 jnet www-data      55 2011-08-07 13:50 b -> /home/someone/someotherthing/subdir/b
lrwxrwxrwx 1 jnet www-data      55 2011-08-07 13:50 c -> /home/someone/someotherthing/subdir/c
lrwxrwxrwx 1 jnet www-data      55 2011-08-07 13:50 d -> /home/someone/someotherthing/subdir/d
lrwxrwxrwx 1 jnet www-data      55 2011-08-07 13:50 e -> /home/someone/someotherthing/subdir/e

我想要一个命令,该命令将找到所有符号链接并重新链接到相同的位置,但位于/mnt/home而不是/home之下

是否存在这样的命令?

55
Josh

没有命令可以重新定向符号链接,您所要做的就是删除它并创建另一个。假设您有GNU)实用程序(例如,在非嵌入式Linux或Cygwin下),则可以使用find-lname主对象按其目标匹配符号链接,和readlink读取链接的内容。

find /mnt/home/someone/something -lname '/home/someone/*' \
     -exec sh -c 'ln -snf "/mnt$(readlink "$0")" "$0"' {} \;

使这些符号链接相对更好。许多Linux发行版中都有一个方便的小实用程序 symlinks (最初由Mark Lords,现在由J. Brandt Buckley维护)。在移动之前或在如上所述恢复有效链接之后,运行symlinks -c /mnt/home/someone/something将指定目录下的所有绝对符号链接转换为相对符号链接,除非它们跨越文件系统边界。

57

我知道这并不是作者所要求的,但似乎他们已经有了答案,所以我为像我这样偶然发现此问题的其他人添加了这个答案。

如果需要更灵活的解决方案,例如具有一堆损坏的符号链接,可以通过替换部分符号链接的目标进行修复,则以下内容将有所帮助。

例如。更改用户名后,在完成移动之后,在许多链接的目标中将旧用户名替换为新用户名。创建一个名为replace-simlinks的脚本,如下所示:

#!/bin/bash
link=$1
# grab the target of the old link
target=$(readlink -- "$1")

# replace the first occurrence of oldusername with newusername in the target string
target=${target/oldusername/newusername}

# Test the link creation
echo ln -s -- "$target" "$link"

# If the above echo shows the correct commands are being issued, then uncomment the following lines and run the command again
#rm "$link"
#ln -s "$target" "$link"

并使用以下命令调用它:

find /home/newusername/ -lname '/home/oldusername/*' -exec ~/bin/replace-simlinks {} \;

希望这对某人有帮助

编辑:感谢Gilles在此脚本上的启动以及有关使用symlinks脚本使链接相对的提示。

13
Gerry

创建/home作为到/mnt/home的符号链接,所有现有的符号链接将再次有效。

4
Keith Thompson