是否有可能找到当前在KornShell(ksh)中执行的脚本的完整路径?
即。如果我的脚本在/opt/scripts/myscript.ksh
,我可以在该脚本中以编程方式发现/opt/scripts/myscript.ksh
吗?
谢谢,
答案 0 :(得分:27)
您可以使用:
## __SCRIPTNAME - name of the script without the path
##
typeset -r __SCRIPTNAME="${0##*/}"
## __SCRIPTDIR - path of the script (as entered by the user!)
##
__SCRIPTDIR="${0%/*}"
## __REAL_SCRIPTDIR - path of the script (real path, maybe a link)
##
__REAL_SCRIPTDIR=$( cd -P -- "$(dirname -- "$(command -v -- "$0")")" && pwd -P )
答案 1 :(得分:9)
在korn shell中,如果你在相关脚本中采购,所有这些$ 0解决方案都会失败。获得所需内容的正确方法是使用$ _
$ cat bar
echo dollar under is $_
echo dollar zero is $0
$ ./bar
dollar under is ./bar
dollar zero is ./bar
$ . ./bar
dollar under is bar
dollar zero is -ksh
注意那里的最后一行?使用$ _。至少在Korn。 YMMV in bash,csh,et al ..
答案 2 :(得分:8)
如何调用脚本存储在变量$ 0中。您可以使用readlink
获取绝对文件名:
readlink -f "$0"
答案 3 :(得分:8)
好吧,我花了一段时间,但这个很简单,它尖叫。
_SCRIPTDIR=$(cd $(dirname $0);echo $PWD)
因为CD在带有$()的衍生shell中运行,所以它不会影响当前脚本。
答案 4 :(得分:4)
变量$ RPATH包含真实文件的相对路径或真实文件的真实路径。
CURPATH=$( cd -P -- "$(dirname -- "$(command -v -- "$0")")" && pwd -P )
CURLOC=$CURPATH/`basename $0`
if [ `ls -dl $CURLOC |grep -c "^l" 2>/dev/null` -ne 0 ];then
ROFFSET=`ls -ld $CURLOC|cut -d ">" -f2 2>/dev/null`
RPATH=`ls -ld $CURLOC/$ROFFSET 2>/dev/null`
else
RPATH=$CURLOC
fi
echo $RPATH
答案 5 :(得分:2)
readlink -f
将是最好的,因为它可以解析为目录和文件找到的每个链接。
在mac os x上没有readlink -f
(除了可能通过macports),所以你只能使用readlink
来获取特定符号链接文件的目的地。
$(cd -P ... pwd -P)
技术很不错,但只能解析导致脚本的目录的链接,如果脚本本身是符号链接,它就不起作用
此外,还有一个未提及的案例:当您通过将脚本作为参数传递给shell(/bin/sh /path/to/myscript.sh
)来启动脚本时,$0
在这种情况下不可用
我看了一下mysql“二进制文件”,其中很多都是shell脚本;现在我明白为什么他们要求--basedir
选项或需要从特定的工作目录启动;这是因为没有很好的解决方案来找到目标脚本
答案 6 :(得分:2)
这就是我所做的:
if [[ $0 != "/"* ]]; then
DIR=`pwd`/`dirname $0`
else
DIR=`dirname $0`
fi
答案 7 :(得分:1)
这也有效,但如果它是一个链接,它不会给出“真正的”路径。它更简单,但不太精确。
SCRIPT_PATH="$(whence ${0})"
答案 8 :(得分:1)
尝试使用哪个命令。
which scriptname
将为您提供脚本的完整限定名称及其绝对路径
答案 9 :(得分:0)
我升级了Edward Staudt的答案,以便能够处理绝对路径的符号链接,以及链接链。
DZERO=$0
while true; do
echo "Trying to find real dir for script $DZERO"
CPATH=$( cd -P -- "$(dirname -- "$(command -v -- "$DZERO")")" && pwd -P )
CFILE=$CPATH/`basename $DZERO`
if [ `ls -dl $CFILE | grep -c "^l" 2>/dev/null` -eq 0 ];then
break
fi
LNKTO=`ls -ld $CFILE | cut -d ">" -f2 | tr -d " " 2>/dev/null`
DZERO=`cd $CPATH ; command -v $LNKTO`
done
丑陋,但有效...... 运行此命令后,路径为$ CPATH,文件为$ CFILE
答案 10 :(得分:0)
使用$ _提供最后一个命令。
>source my_script
如果我发出两次命令,则有效:
>source my_script
>source my_script
如果我使用不同的命令序列:
>who
>source my_script
$ _变量返回“who”
答案 11 :(得分:-1)
尝试使用:
dir = $(dirname $0)