给定一个绝对路径或相对路径(在类unix系统中),我希望在解析任何中间符号链接之后确定目标的完整路径。同时还可以解析~用户名符号。
如果目标是一个目录,则可以将chdir()放入该目录,然后调用getcwd(),但我确实希望从shell脚本而不是编写C helper来完成此操作。不幸的是,shell倾向于试图向用户隐藏符号链接的存在(这是OS X上的bash):
$ ls -ld foo bar
drwxr-xr-x 2 greg greg 68 Aug 11 22:36 bar
lrwxr-xr-x 1 greg greg 3 Aug 11 22:36 foo -> bar
$ cd foo
$ pwd
/Users/greg/tmp/foo
$
我想要的是一个函数resolve(),这样当从上面的例子中的tmp目录执行时,resolve("foo") == "/Users/greg/tmp/bar"。
readlink -f "$path"
编者注:上述内容适用于GNU readlink和FreeBSD/PC-BSD/OpenBSD readlink,但不适用于10.11版本的OS X。
GNU readlink提供了额外的相关选项,例如-m用于解析符号链接,无论最终目标是否存在。
注意,自从GNU coreutils 8.15(2012-01-06)以来,有一个realpath程序可用,它不那么迟钝,而且比上面的程序更灵活。它还兼容同名的FreeBSD util。它还包括在两个文件之间生成相对路径的功能。
realpath $path
[管理员添加以下评论由halloleo -danorton]
对于Mac OS X(至少10.11.x),使用不带-f选项的readlink:
readlink $path
编者注:这将不会递归地解析符号链接,因此不会报告最终目标;例如,给定指向b的符号链接a, b又指向c,这将只报告b(并且不会确保它作为绝对路径输出)。
在OS X上使用以下perl命令来填补缺少readlink -f功能的空白:
perl -MCwd -le 'print Cwd::abs_path(shift)' "$path"