我有一个目录树,其中有一堆指向文件的符号链接/home
...但是,我已经转移/home
到/mnt/home
并需要一种方法来“重新链接”所有符号链接。是否存在这样的功能或者我需要编写脚本来执行此操作?
作为一个例子,我有类似以下内容:
[root@trees ~]# 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
存在这样的命令吗?
答案1
没有命令可以重定向符号链接,您所能做的就是删除它并创建另一个。假设您有 GNU 实用程序(例如,在非嵌入式 Linux 或 Cygwin 下),您可以使用主要-lname
的 来find
按目标匹配符号链接,并readlink
读取链接的内容。未经测试:
find /mnt/home/someone/something -lname '/home/someone/*' \
-exec sh -c 'ln -snf "/mnt$(readlink "$1")" "$1"' sh {} \;
最好使这些符号链接具有相对性。假设ln
来自 GNU coreutils 8.22,只需将该-r
选项传递ln
给其他选项,它就会将目标转换为相对路径。对于较旧的系统或批量重写有效链接,有一个方便的小实用程序,称为symlinks
(最初由 Mark Lord,现在由 J. Brandt Buckley 维护),存在于许多 Linux 发行版中。
在移动之前,或者在如上所述恢复有效链接之后,运行symlinks -c /mnt/home/someone/something
将指定目录下的所有绝对符号链接转换为相对符号链接,除非它们跨越文件系统边界。
答案2
我知道这并不完全是作者所要求的,但似乎他们已经有了答案,所以我为像我这样偶然发现这个问题的其他人添加这个答案。
如果需要更灵活的解决方案,例如有一堆损坏的符号链接,可以通过替换部分符号链接的目标来修复,以下内容应该会有所帮助。
例如。更改用户名后,在移动完成后,在许多链接的目标中用新用户名替换旧用户名。创建一个名为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 启动此脚本以及有关使用符号链接脚本使链接相对的提示。
答案3
创建/home
为 的符号链接/mnt/home
,所有现有符号链接将再次有效。
答案4
我写了一个fix_broken_symlinks
bash脚本工具:
我希望它能成为流行的 的配套工具symlinks
,它可以做一些其他有用的事情。
这是我的工具:
# find all broken symlinks
fix_broken_symlinks path/to/dir
# dry-run fix them
fix_broken_symlinks path/to/dir find_regex replacement_str
# actually fix them (passing `-f` to force it)
fix_broken_symlinks path/to/dir find_regex replacement_str -f
我付出了很多努力来获得非常漂亮且一致的输出。
运行示例:
/home/gabriel/GS/dev/RESEARCH$ fix_broken_symlinks . '/home/gabriel/GS/dev' '/home/gabriel/GS/dev/RESEARCH' -f
4 broken symlinks found!
************************************************************************
'--force' is on! Writing new **relative** symlinks!
************************************************************************
1/4: BROKEN: './lldb/Link to Debuggers_General' -> '/home/gabriel/GS/dev/Debuggers_General'
FIXED : './lldb/Link to Debuggers_General' -> '/home/gabriel/GS/dev/RESEARCH/Debuggers_General'
FINAL : './lldb/Link to Debuggers_General' -> '../Debuggers_General'
2/4: BROKEN: './Link to notes - Gabriel.odt' -> '/home/gabriel/GS/dev/notes - Gabriel.odt'
FIXED : './Link to notes - Gabriel.odt' -> '/home/gabriel/GS/dev/RESEARCH/notes - Gabriel.odt'
FINAL : './Link to notes - Gabriel.odt' -> 'notes - Gabriel.odt'
3/4: BROKEN: './books/Link to 104The Pragmatic Programmer, From Journeyman To Master - Andrew Hunt, David Thomas - Addison Wesley - 1999.pdf-1.desktop' -> '/home/gabriel/GS/dev/Design_Docs/104The Pragmatic Programmer, From Journeyman To Master - Andrew Hunt, David Thomas - Addison Wesley - 1999.pdf-1.desktop'
FIXED : './books/Link to 104The Pragmatic Programmer, From Journeyman To Master - Andrew Hunt, David Thomas - Addison Wesley - 1999.pdf-1.desktop' -> '/home/gabriel/GS/dev/RESEARCH/Design_Docs/104The Pragmatic Programmer, From Journeyman To Master - Andrew Hunt, David Thomas - Addison Wesley - 1999.pdf-1.desktop'
FINAL : './books/Link to 104The Pragmatic Programmer, From Journeyman To Master - Andrew Hunt, David Thomas - Addison Wesley - 1999.pdf-1.desktop' -> '../Design_Docs/104The Pragmatic Programmer, From Journeyman To Master - Andrew Hunt, David Thomas - Addison Wesley - 1999.pdf-1.desktop'
4/4: BROKEN: './books/TDD--James Grenning Test-Driven Dev for Embedded C/pragprog.com/Link to TDD_code' -> '/home/gabriel/GS/dev/books/TDD_code'
FIXED : './books/TDD--James Grenning Test-Driven Dev for Embedded C/pragprog.com/Link to TDD_code' -> '/home/gabriel/GS/dev/RESEARCH/books/TDD_code'
FINAL : './books/TDD--James Grenning Test-Driven Dev for Embedded C/pragprog.com/Link to TDD_code' -> '../../TDD_code'
************************************************************************
'--force' is on! New **relative** symlinks written!
************************************************************************
Run 'fix_broken_symlinks` "."' one more time to check if any symlinks are
still broken.
real 0m0.157s
user 0m0.101s
sys 0m0.086s
细节
我刚刚编写了一个工具,用来修复近 100 个损坏的符号链接。它被称为fix_broken_symlinks.sh
,这是我的一部分eRCAGuy_dotfiles回购。
获取方法如下:
# download it and make it executable
wget https://raw.githubusercontent.com/ElectricRCAircraftGuy/eRCaGuy_dotfiles/master/useful_scripts/fix_broken_symlinks.sh
chmod +x fix_broken_symlinks
# help menu, with tons of info., & examples
./fix_broken_symlinks -h
一般用法和示例:
# General usage
fix_broken_symlinks path/to/dir find_regex replacement_str
# (Dry run) fix all broken symlinks in the current dir (.) by replacing their
# target paths with John's home dir instead of Gabriel's.
fix_broken_symlinks . '/home/gabriel/some/dir' 'home/john/some/dir'
# Pass `-f` to force it to actually apply the changes
fix_broken_symlinks . '/home/gabriel/some/dir' 'home/john/some/dir' -f
从帮助菜单:
'fix_broken_symlinks' version 0.1.0
USAGE
fix_broken_symlinks [options] <dir> [<find_regex> <replacement_string>]
DESCRIPTION
Find all broken symlinks in directory 'dir', then extract the target paths they point to, search
those paths for 'find_regex', and replace those findings with 'replacement_string'. Finally,
recreate the symlinks as relative symlinks with those replacements to the target paths in
place.
If the 'find_regex' and 'replacement_string' are not provided, it will simply find and print out
the broken symlinks as they currently are.
All runs are dry-runs unless you use '--force'.
OPTIONS
-h, -?, --help
Print help menu
-v, --version
Print version information.
--run_tests
Run unit tests.
-d, --debug
Turn on debug prints.
-f, --force
Actually do the symlink replacements. With*out* this option, all runs are dry runs.
EXAMPLE USAGES:
fix_broken_symlinks -h
Print help menu.
fix_broken_symlinks --help
Print help menu.
fix_broken_symlinks .
Recursively find all broken symlinks in the current directory (.).
fix_broken_symlinks . '/home/gabriel/some/dir' 'home/john/some/dir'
(Dry run) fix all broken symlinks in the current dir (.) by replacing their target paths
with John's home dir instead of Gabriel's.
fix_broken_symlinks . '/home/gabriel/some/dir' 'home/john/some/dir' -f
(Real run) fix all broken symlinks in the current dir (.) by replacing their target paths
with John's home dir instead of Gabriel's. **Relative** symlinks will be created in the end.
我使用的其他工具有:
使用以下命令手动修复一次性损坏的符号链接:
注意:
-n
如果您要替换的符号链接是目录,则这是必需的。有关详细信息,请参阅以我的评论开头的讨论:如何“重新链接”大量损坏的符号链接?# NB: **All** of these options are important, and what I want. See 'man ln' # for what each does. ln -svnri target_path symlink_path
将所有符号链接从绝对符号链接转换为相对符号链接:
symlinks -rsvt . # dry run symlinks -rsvc . # the real replacement
在 Ubuntu 中安装
symlinks
:sudo add-apt-repository universe sudo apt update sudo apt install symlinks
看:https://www.makeuseof.com/how-to-find-and-fix-broken-symlinks-in-linux/
更多我的笔记
看:
fix_broken_symlinks -h
- 我在本文档中的注释如下:eRCaGuy_dotfiles/git 和 Linux cmd、帮助、提示和技巧 - Gabriel.txt。搜索它
= Symlink Utilities: =
。