Gre*_*ill 211 bash shell scripting symlink
给定绝对或相对路径(在类Unix系统中),我想在解析任何中间符号链接后确定目标的完整路径.奖励积分也可以同时解析〜用户名表示法.
如果目标是目录,则可以将chdir()放入目录然后调用getcwd(),但我真的想从shell脚本而不是编写C帮助程序.不幸的是,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
$
Run Code Online (Sandbox Code Playgroud)
我想要的是一个函数resolve(),这样当从上例中的tmp目录执行时,解析("foo")=="/ Users/greg/tmp/bar".
pix*_*eat 386
readlink -f "$path"
Run Code Online (Sandbox Code Playgroud)
编者注:以上内容适用于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
Run Code Online (Sandbox Code Playgroud)
对于Mac OS X(通过至少10.11.x),请使用readlink不带-f选项:
readlink $path
Run Code Online (Sandbox Code Playgroud)
编者注:这不会递归地解析符号链接,因此不会报告最终目标; 例如,给定a指向的符号链接指向(仅b指向)c,这只会报告b(并且不会确保它作为绝对路径输出).在OS X上
使用以下perl命令填补缺少的readlink -f功能的空白:
perl -MCwd -le 'print Cwd::abs_path(shift)' "$path"
kau*_*ppi 89
根据标准,pwd -P应该返回解决了符号链接的路径.
C函数char *getcwd(char *buf, size_t size)从unistd.h应具有相同的行为.
tlr*_*son 25
如果您只是想要目录,"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
Run Code Online (Sandbox Code Playgroud)
Gre*_*ory 17
我最喜欢的一个是 realpath foo
realpath - return the canonicalized absolute pathname
realpath expands all symbolic links and resolves references to '/./', '/../' and extra '/' characters in the null terminated string named by path and
stores the canonicalized absolute pathname in the buffer of size PATH_MAX named by resolved_path. The resulting path will have no symbolic link, '/./' or
'/../' components.
Chu*_*ars 10
readlink -e [filepath]
Run Code Online (Sandbox Code Playgroud)
似乎正是你所要求的 - 它接受一个arbirary路径,解析所有符号链接,并返回"真实"路径 - 它可能是所有系统已经拥有的"标准*nix"
其他方式:
# Gets the real path of a link, following all links
myreadlink() { [ ! -h "$1" ] && echo "$1" || (local link="$(expr "$(command ls -ld -- "$1")" : '.*-> \(.*\)$')"; cd $(dirname $1); myreadlink "$link" | sed "s|^\([^/].*\)\$|$(dirname $1)/\1|"); }
# Returns the absolute path to a command, maybe in $PATH (which) or not. If not found, returns the same
whereis() { echo $1 | sed "s|^\([^/].*/.*\)|$(pwd)/\1|;s|^\([^/]*\)$|$(which -- $1)|;s|^$|$1|"; }
# Returns the realpath of a called command.
whereis_realpath() { local SCRIPT_PATH=$(whereis $1); myreadlink ${SCRIPT_PATH} | sed "s|^\([^/].*\)\$|$(dirname ${SCRIPT_PATH})/\1|"; }
Run Code Online (Sandbox Code Playgroud)
小智 5
将一些给定的解决方案放在一起,知道readlink在大多数系统上都可用,但需要不同的参数,这对我在OSX和Debian上运行良好.我不确定BSD系统.也许条件需要仅从OSX中[[ $OSTYPE != darwin* ]]排除-f.
#!/bin/bash
MY_DIR=$( cd $(dirname $(readlink `[[ $OSTYPE == linux* ]] && echo "-f"` $0)) ; pwd -P)
echo "$MY_DIR"
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
152990 次 |
| 最近记录: |