web-dev-qa-db-ja.com

KornShellで現在のスクリプトへの絶対パスを取得できますか?

KornShell(ksh)で現在実行されているスクリプトへの完全なパスを見つけることは可能ですか?

つまり、スクリプトが/opt/scripts/myscript.ksh、そのスクリプト内でプログラムで発見できますか/opt/scripts/myscript.ksh

おかげで、

22
brabster

あなたは使うことができます:

## __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 )
27
Marnix

しばらく時間がかかりましたが、これはとても簡単なので、悲鳴を上げます。

_SCRIPTDIR=$(cd $(dirname $0);echo $PWD)

cDは$()を使用して生成されたシェルで動作するため、現在のスクリプトには影響しません。

9
Mitch Brown

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など).

9
user2639142

スクリプトが呼び出された方法は、変数$ 0に格納されます。 readlinkを使用して、絶対ファイル名を取得できます。

readlink -f "$0"
8
soulmerge

変数$ 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
4
Edward Staudt

_readlink -f_は、ディレクトリとファイルの両方で見つかったすべてのリンクを解決するため、移植可能であれば最適です。

Mac OS Xには_readlink -f_がないため(おそらくMacportsを介して)、readlinkを使用して特定のシンボリックリンクファイルの宛先を取得することしかできません。

$(cd -P ... pwd -P)テクニックは素晴らしいですが、スクリプトにつながるディレクトリのリンクを解決するためにのみ機能し、スクリプト自体がシンボリックリンクである場合は機能しません

また、言及されていない1つのケース:シェルに引数として渡してスクリプトを起動する場合(_/bin/sh /path/to/myscript.sh_)、この場合、_$0_は使用できません

私はmysqlの「バイナリ」を調べました。それらの多くは実際にはシェルスクリプトです。そして今、私は彼らが_--basedir_オプションを要求する理由、または特定の作業ディレクトリから起動する必要がある理由を理解しています。これは、ターゲットスクリプトを特定するための適切なソリューションがないためです。

2
Gruik

これは私がやったことです:

if [[ $0 != "/"* ]]; then
  DIR=`pwd`/`dirname $0`
else
  DIR=`dirname $0`
fi
2
John Nilsson

これも機能しますが、リンクの場合、「真の」パスは提供されません。シンプルですが、正確性は劣​​ります。

SCRIPT_PATH="$(whence ${0})"
1
mtruesdell

どのコマンドを試してください。

which scriptname

スクリプトの完全修飾名とその絶対パスが表示されます

1

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になります。

0
Maciel

$ _を使用すると、最後のコマンドが提供されます。

>source my_script

コマンドを2回発行すると機能します。

>source my_script
>source my_script

別のコマンドシーケンスを使用する場合:

>who
>source my_script

$ _変数は「who」を返します

0
user5948557