我可以在KornShell中获取当前脚本的绝对路径吗?

时间:2009-04-17 11:51:08

标签: shell unix scripting path ksh

是否有可能找到当前在KornShell(ksh)中执行的脚本的完整路径?

即。如果我的脚本在/opt/scripts/myscript.ksh,我可以在该脚本中以编程方式发现/opt/scripts/myscript.ksh吗?

谢谢,

12 个答案:

答案 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)