自动化修复所有损坏链接的过程

Sam*_*man 5 shell-script symlink

我的系统中有很多断开的链接。我写了一个脚本来重新链接所有断开的链接。但是,在脚本运行后, find 将再次向我显示链接仍然存在。

这是我的代码:

find /home/saman -lname '/home/saman/*' -exec \
   sh -c 'ln -snf "/home$(readlink "$0")" "$0"' {} \;
Run Code Online (Sandbox Code Playgroud)

运行上面的命令后,我搜索断开的链接并仍然找到它们:

find . -type l | xargs file | grep broken 
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?

ter*_*don 5

第一个问题是您的find命令只会找到使用完整路径的链接,而不是相对路径。为了显示:

$ ln -s /home/terdon/foo/NonExistantFile foo
$ ln -s NonExistantFile bar

$ tree
.
|-- bar -> NonExistantFile
`-- foo -> /home/terdon/foo/NonExistantFile
Run Code Online (Sandbox Code Playgroud)

在上面的示例中,我创建了两个断开的链接。第一个使用绝对路径,第二个使用相对路径。如果我现在尝试您的find命令(使用重新echo链接命令而不是运行它以便我们可以看到它在做什么),则只会找到两者之一:

$ find . -lname '/home/terdon/*' -exec \
    sh -c 'echo ln -snf "/home$(readlink "$0")" "$0"' {} \; 
ln -snf /home/home/terdon/foo/NonExistantFile ./foo
Run Code Online (Sandbox Code Playgroud)

第二个问题是你的路径是错误的。您正在将链接重新创建为"/home$(readlink "$0")" "$0". 该readlink命令已经显示完整路径,因此添加/home到它的结果/home/home/...不是您想要的。

更重要的是,你正在尝试的是不可能的。如果链接断开,则意味着其目标不存在。由于目标不存在,您不能简单地重新链接文件,无处将其链接. 您唯一能做的就是重新创建链接的目标。然而,这不太可能很有用,因为它只会让您的断开链接指向新的空文件。如果这确实是你想要做的,你可以尝试

 find . -type l -exec sh -c 'touch "$(readlink "{}")" ' \; 
Run Code Online (Sandbox Code Playgroud)

最后,您可能想要创建一个更复杂的脚本 i) 找到所有断开的链接 ii) 在您的机器上搜索与链接目标名称相同的文件 iii) 向您显示它们的列表 iv) 询问您是哪个它现在应该链接到一个。