2011-07-23 653 views
1

假设我在文件“file1”上创建了一个符号链接“file2”,位于当前位置上方的两个目录(例如“ln -s ../../file1 file2” 。但现在假设“file1”也是一个文件“file0”从它的位置向下两个目录的符号链接(假设它的相对路径是dir1/dir2/file0)符号链接到符号链接...部分规范化

我宁愿如果“ file1“的符号链接包含一个相对URL,它将转到file0”../../dir1/dir2/file0“,而不仅仅是”../../file1“。后者只是间接指向该文件。

这样做的好方法是什么?

我可以与readlink一起破解一些东西。但我仍然希望有一种我不考虑或忽视的“更好”方式。

+0

应该是'canonization':-) – TMS

+0

这个问题与许多使用搜索关键词“绝对”,“相对”和“路径”相关,如[BASH:将绝对路径转换为给定当前目录的相对路径] (http://stackoverflow.com/questions/2564634/bash-convert-absolute-path-into-relative-path-given-a-current-directory)。不幸的是,我还没有答案可以接受。 –

+0

你的评论让我记得...看到其他答案。 – TMS

回答

1

这将递归测试文件和检索

#!/bin/bash 
linkfile="$1" 
while test -L "$linkfile" ; do 
linkfile="$(dirname ${linkfile})/$(readlink ${linkfile})" 
done 
perl -e '$x=shift; while ($x =~ s#//+#/#g) {} ; while ($x =~ s#/\./#/#g) {} ; while ($x =~ s#/([^\.]|[^\.][^/]+?|\.[^\.]+?)/\.\./#/#g) {} ; while ($x =~ s#^([^\.]|[^\.][^/]+?|\.[^\.]+?)/\.\./#/#g) {} ; $x =~ s#^\./##; print "$x\n";' "$linkfile" 

如果保存完整的相对路径,然后删除不必要的“./”和‘富/../’,作为‘canonical.bash’那你就用它

$ ln -s `canonical.bash foo` bar 

正则表达式不会降低少数情况下,像“/..x/../”和“../foo/”(如果富/在你的$ PWD)但应该是坚固的。

+0

这个脚本似乎回答了我问的问题。然而,它并没有在所有情况下传递最短的相对路径。这个例子失败了:让“/ home/user/dir1”包含一个包含“file.txt”的目录“dir2”。假设“link1”也存在并指向“dir2/file.txt”和“link2”,并且指向“../dir1/../dir1/link1”。该脚本按预期方式返回“../dir1/dir2/file.txt”而不是“dir2/file.txt”。 –

+0

我不满足于不得不求助于perl。没有它的解决方案会更优雅。 –

+0

正如你在另一个问题中所看到的那样,将相对路径转化为规范路径具有挑战性。我扔了一个快速的正则表达式来处理它,并有Perl模块可以更好地处理它,但我不知道有一个标准的shell命令来完成它。 – brightlancer

0

不,这是非常具体的,我认为你将不得不使用readlink并自己实现它。

0

现在我记得了!我看到大约15年前实现这个功能的工具!见man symlinks(1)symlinks -c。如果这不是你想要的,我想你的需求是非常明确的,你必须自己编写代码......(如果我记得很清楚,我还为处理我的磁盘上的符号链接做了一些实用工具...)。 PERL是一个伟大的语言。

+0

这是一个有趣的工具(在Ubuntu 10.04版本中),但它并没有做我想要完成的工作。我在StackOverflow发现了一些bash脚本,它们可以解决这个问题,但没有什么能完全令人满意。我现在考虑投入时间写我自己的。希望不必这样做。如果我写一些我感到自豪的作品,我会发布。 –