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 シェルでは、問題のスクリプトをソースしている場合、これらの $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 は $() を使用して生成されたシェルで動作するため、現在のスクリプトには影響しません。
スクリプトがどのように呼び出されたかは、変数 $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
これは私がしたことです:
if [[ $0 != "/"* ]]; then
DIR=`pwd`/`dirname $0`
else
DIR=`dirname $0`
fi
readlink -f
ディレクトリとファイルの両方で見つかったすべてのリンクを解決するため、移植可能であれば最高です。
mac os x にはreadlink -f
(おそらく macports 経由を除いて)存在しないためreadlink
、特定のシンボリック リンク ファイルの宛先を取得するためにのみ使用できます。
この$(cd -P ... pwd -P)
手法は優れていますが、スクリプトにつながるディレクトリのリンクを解決するためにのみ機能します。スクリプト自体がシンボリックリンクの場合は機能しません
また、言及されていない1つのケース:スクリプトをシェルに引数として渡して起動する場合(/bin/sh /path/to/myscript.sh
)、$0
この場合は使用できません
私はmysqlの「バイナリ」を調べましたが、それらの多くは実際にはシェルスクリプトです。--basedir
そして今、彼らがオプションを要求する理由、または特定の作業ディレクトリから起動する必要がある理由を理解しました。これは、対象のスクリプトを見つけるための適切な解決策がないためです。
どのコマンドを試してください。
which scriptname
スクリプトの完全修飾名とその絶対パスが表示されます
これも機能しますが、リンクの場合は「真の」パスは提供されません。より単純ですが、正確さは劣ります。
SCRIPT_PATH="$(whence ${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 です
$_ を使用すると、最後のコマンドが提供されます。
>source my_script
コマンドを 2 回発行すると機能します。
>source my_script
>source my_script
別のコマンド シーケンスを使用する場合:
>who
>source my_script
$_ 変数は「who」を返します
これを使用してみてください:
dir = $(dirname $0)