是否可以找出当前在 KornShell (ksh) 中执行的脚本的完整路径?
即,如果我的脚本在/opt/scripts/myscript.ksh
其中,我可以在该脚本中以编程方式发现/opt/scripts/myscript.ksh
吗?
谢谢,
你可以使用:
## __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 )
在 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
注意到最后一行了吗?使用 $_。至少在科恩。bash、csh 等中的 YMMV
好吧,我花了一段时间,但这一个是如此简单,以至于尖叫。
_SCRIPTDIR=$(cd $(dirname $0);echo $PWD)
由于 CD 在生成的 shell 中使用 $() 运行,因此不会影响当前脚本。
脚本的调用方式存储在变量 $0 中。您可以使用readlink
获取绝对文件名:
readlink -f "$0"
变量 $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
readlink -f
如果它是可移植的,那将是最好的,因为它可以解析为目录和文件找到的每个链接。
在 mac os x 上没有readlink -f
(可能通过 macports 除外),因此您只能用于readlink
获取特定符号链接文件的目标。
该$(cd -P ... pwd -P)
技术很好,但仅适用于解析指向脚本的目录的链接,如果脚本本身是符号链接,则它不起作用
此外,还有一个没有提到的情况:当您通过将脚本作为参数传递给 shell ( /bin/sh /path/to/myscript.sh
) 来启动脚本时,$0
在这种情况下不可用
我查看了 mysql “二进制文件”,其中许多实际上是 shell 脚本;现在我明白了为什么他们要求--basedir
选择或需要从特定的工作目录启动;这是因为没有很好的解决方案来定位目标脚本
这就是我所做的:
if [[ $0 != "/"* ]]; then
DIR=`pwd`/`dirname $0`
else
DIR=`dirname $0`
fi
这也有效,尽管如果它是链接,它不会给出“真实”路径。它更简单,但不太精确。
SCRIPT_PATH="$(whence ${0})"
试试哪个命令。
which scriptname
将为您提供脚本的完整限定名及其绝对路径
我升级了 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
尝试使用这个:
dir = $(dirname $0)
使用 $_ 提供最后一个命令。
>source my_script
如果我两次发出命令,则有效:
>source my_script
>source my_script
如果我使用不同的命令序列:
>who
>source my_script
$_ 变量返回“谁”