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 )
しばらく時間がかかりましたが、これはとても簡単なので、悲鳴を上げます。
_SCRIPTDIR=$(cd $(dirname $0);echo $PWD)
cDは$()を使用して生成されたシェルで動作するため、現在のスクリプトには影響しません。
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
そこの最後の行に気づきましたか? $ _を使用します。少なくともコーンでは。 YMMV(bash、cshなど).
スクリプトが呼び出された方法は、変数$ 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)
テクニックは素晴らしいですが、スクリプトにつながるディレクトリのリンクを解決するためにのみ機能し、スクリプト自体がシンボリックリンクである場合は機能しません
また、言及されていない1つのケース:シェルに引数として渡してスクリプトを起動する場合(_/bin/sh /path/to/myscript.sh
_)、この場合、_$0
_は使用できません
私はmysqlの「バイナリ」を調べました。それらの多くは実際にはシェルスクリプトです。そして今、私は彼らが_--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になります。
$ _を使用すると、最後のコマンドが提供されます。
>source my_script
コマンドを2回発行すると機能します。
>source my_script
>source my_script
別のコマンドシーケンスを使用する場合:
>who
>source my_script
$ _変数は「who」を返します