Question

Is it possible to find out the full path to the script that is currently executing in KornShell (ksh)?

i.e. if my script is in /opt/scripts/myscript.ksh, can I programmatically inside that script discover /opt/scripts/myscript.ksh ?

Thanks,

Was it helpful?

Solution

You could use:

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

OTHER TIPS

In korn shell, all of these $0 solutions fail if you are sourcing in the script in question. The correct way to get what you want is to use $_

$ 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

Notice the last line there? Use $_. At least in Korn. YMMV in bash, csh, et al..

How the script was called is stored in the variable $0. You can use readlink to get the absolute file name:

readlink -f "$0"

Well it took me a while but this one is so simple it screams.

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

since the CD operates in the spawned shell with $() it doesn't affect the current script.

The variable $RPATH contains the relative path to the real file or the real path for a real file.

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

This is what I did:

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

readlink -f would be the best if it was portable, because it resolves every links found for both directories and files.

On mac os x there is no readlink -f (except maybe via macports), so you can only use readlink to get the destination of a specific symbolic link file.

The $(cd -P ... pwd -P) technique is nice but only works to resolve links for directories leading to the script, it doesn't work if the script itself is a symlink

Also, one case that wasn't mentioned : when you launch a script by passing it as an argument to a shell (/bin/sh /path/to/myscript.sh), $0 is not usable in this case

I took a look to mysql "binaries", many of them are actually shell scripts ; and now i understand why they ask for a --basedir option or need to be launched from a specific working directory ; this is because there is no good solution to locate the targeted script

This works also, although it won't give the "true" path if it's a link. It's simpler, but less exact.

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

Try which command.

which scriptname

will give you the full qualified name of the script along with its absolute path

I upgraded the Edward Staudt's answer, to be able to deal with absolute-path symbolic links, and with chains of links too.

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

Ugly, but works... After run this, the path is $CPATH and the file is $CFILE

Using $_ provides the last command.

>source my_script

Works if I issue the command twice:

>source my_script
>source my_script

If I use a different sequence of commands:

>who
>source my_script

The $_ variable returns "who"

Try using this:

dir = $(dirname $0)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top