如何解析shell脚本中的符号链接
给定绝对路径或相对路径(在类Unix系统中),我想在解析任何中间符号链接后确定目标的完整路径。 奖励积分也可以同时解析〜用户名表示法。
如果目标是一个目录,可以将chdir()放到目录中,然后调用getcwd(),但我真的想从shell脚本执行此操作,而不是编写C助手。 不幸的是,shell有一种倾向,试图隐藏用户的符号链接的存在(这是OS X上的混淆):
$ 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”。
根据标准, pwd -P
应该返回解析了符号链接的路径。
来自unistd.h
C函数char *getcwd(char *buf, size_t size)
应该具有相同的行为。
getcwd pwd
readlink -f "$path"
编者按:上面的代码与GNU readlink
和FreeBSD / PC-BSD / OpenBSD readlink
,但不在10.11版本的OS X上。
GNU readlink
提供了额外的相关选项,如-m
用于解析符号链接,无论最终目标是否存在。
请注意,自GNU coreutils 8.15(2012-01-06)以来,有一个可用的实际路径程序比以上更不灵活和更灵活。 它也与同名的FreeBSD util兼容。 它还包括在两个文件之间生成相对路径的功能。
realpath $path
[下面的管理添加评论来自halloleo -danorton]
对于Mac OS X(至少通过10.11.x),请使用不带-f
选项的readlink
:
readlink $path
编者按:这不会解决符号链接递归,因此不会报告最终目标; 例如,给定符号链接a
指向b
,后者又指向c
,这将只报告b
(并且不会确保它被输出为绝对路径)。
在OS X上使用以下perl
命令来填补缺失readlink -f
功能的空白:
perl -MCwd -le 'print Cwd::abs_path(shift)' "$path"
“pwd -P”似乎可以工作,如果你只是想要目录,但如果由于某种原因,你想要的实际可执行文件的名称,我认为这不会有帮助。 这是我的解决方案:
#!/bin/bash
# get the absolute path of the executable
SELF_PATH=$(cd -P -- "$(dirname -- "$0")" && pwd -P) && SELF_PATH=$SELF_PATH/$(basename -- "$0")
# resolve symlinks
while [[ -h $SELF_PATH ]]; do
# 1) cd to directory of the symlink
# 2) cd to the directory of where the symlink points
# 3) get the pwd
# 4) append the basename
DIR=$(dirname -- "$SELF_PATH")
SYM=$(readlink "$SELF_PATH")
SELF_PATH=$(cd "$DIR" && cd "$(dirname -- "$SYM")" && pwd)/$(basename -- "$SYM")
done
链接地址: http://www.djcxy.com/p/9735.html