在Linux上,readlink实用程序接受附加链接后面的选项-f。这似乎不适用于Mac和基于BSD的系统。等价的是什么?
下面是一些调试信息:
$ which readlink; readlink -f
/usr/bin/readlink
readlink: illegal option -f
usage: readlink [-n] [file ...]
在Linux上,readlink实用程序接受附加链接后面的选项-f。这似乎不适用于Mac和基于BSD的系统。等价的是什么?
下面是一些调试信息:
$ which readlink; readlink -f
/usr/bin/readlink
readlink: illegal option -f
usage: readlink [-n] [file ...]
当前回答
这个呢?
function readlink() {
DIR="${1%/*}"
(cd "$DIR" && echo "$(pwd -P)")
}
其他回答
这是一个便携式壳函数,应该在任何Bourne可比壳工作。 它将解决相对路径标点符号”..或者。”以及取消对符号链接的引用。
如果由于某种原因,您没有realpath(1)命令或readlink(1),则可以将其别名化。
which realpath || alias realpath='real_path'
享受:
real_path () {
OIFS=$IFS
IFS='/'
for I in $1
do
# Resolve relative path punctuation.
if [ "$I" = "." ] || [ -z "$I" ]
then continue
elif [ "$I" = ".." ]
then FOO="${FOO%%/${FOO##*/}}"
continue
else FOO="${FOO}/${I}"
fi
## Resolve symbolic links
if [ -h "$FOO" ]
then
IFS=$OIFS
set `ls -l "$FOO"`
while shift ;
do
if [ "$1" = "->" ]
then FOO=$2
shift $#
break
fi
done
IFS='/'
fi
done
IFS=$OIFS
echo "$FOO"
}
此外,如果有人对这里感兴趣,我将介绍如何在100%纯shell代码中实现basename和dirname:
## http://www.opengroup.org/onlinepubs/000095399/functions/dirname.html
# the dir name excludes the least portion behind the last slash.
dir_name () {
echo "${1%/*}"
}
## http://www.opengroup.org/onlinepubs/000095399/functions/basename.html
# the base name excludes the greatest portion in front of the last slash.
base_name () {
echo "${1##*/}"
}
您可以在我的谷歌站点上找到这个shell代码的更新版本:http://sites.google.com/site/jdisnard/realpath
编辑: 此代码是根据2-clause (freeBSD风格)许可的条款授权的。 从上面的超链接到我的网站,可以找到许可证的副本。
真正的平台独立也是r -online
readlink(){ RScript -e "cat(normalizePath(commandArgs(T)[1]))" "$1";}
要实际模拟readlink -f <path>,需要使用$2而不是$1。
这是我所使用的:
-f %N $your_path
解决这个问题并在安装了Homebrew或FreeBSD的Mac上启用readlink功能的最简单方法是安装“coreutils”包。在某些Linux发行版和其他POSIX操作系统上可能也是必需的。
例如,在FreeBSD 11中,我通过调用:
# PKG安装coreutils
在使用Homebrew的MacOS上,命令将是:
$ brew install coreutils
不太确定为什么其他答案如此复杂,这就是它的全部。文件并没有在不同的地方,只是还没有安装。
我已经简单地粘贴以下到我的bash脚本的顶部:
#!/usr/bin/env bash -e
declare script=$(basename "$0")
declare dirname=$(dirname "$0")
declare scriptDir
if [[ $(uname) == 'Linux' ]];then
# use readlink -f
scriptDir=$(readlink -f "$dirname")
else
# can't use readlink -f, do a pwd -P in the script directory and then switch back
if [[ "$dirname" = '.' ]];then
# don't change directory, we are already inside
scriptDir=$(pwd -P)
else
# switch to the directory and then switch back
pwd=$(pwd)
cd "$dirname"
scriptDir=$(pwd -P)
cd "$pwd"
fi
fi
并删除了readlink -f的所有实例。$scriptDir和$script将可用于脚本的其余部分。
虽然这并不适用于所有符号链接,但它适用于所有系统,并且对于大多数用例来说已经足够好了,它将目录切换到包含该目录的文件夹,然后执行pwd -P以获得该目录的实际路径,最后切换回原始目录。