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)
我究竟做错了什么?
第一个问题是您的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) 询问您是哪个它现在应该链接到一个。