Могу ли я получить абсолютный путь к текущему script в KornShell?

Можно ли узнать полный путь к script, который в настоящее время выполняется в KornShell (ksh)?

то есть. если мой script находится в /opt/scripts/myscript.ksh, я могу программно внутри этого script обнаружить /opt/scripts/myscript.ksh?

Спасибо,

Ответ 1

Вы можете использовать:

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

Ответ 2

В оболочке korn все эти $0 решения терпят неудачу, если вы работаете в script. Правильный способ получить то, что вы хотите, это использовать $_

$ 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 и др.

Ответ 3

Как вызывается script, сохраняется в переменной $0. Вы можете использовать readlink для получения абсолютного имени файла:

readlink -f "$0"

Ответ 4

Ну, это заняло у меня некоторое время, но это так просто, что он кричит.

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

поскольку CD работает в порожденной оболочке с $(), это не влияет на текущий script.

Ответ 5

Переменная $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

Ответ 6

readlink -f был бы лучшим, если бы он был переносимым, потому что он разрешает все ссылки, найденные как для каталогов, так и для файлов.

В mac os x нет readlink -f (кроме, может быть, через macports), поэтому вы можете использовать readlink для получения адресата определенного символического файла ссылки.

Метод $(cd -P ... pwd -P) хорош, но работает только для разрешения ссылок на каталоги, ведущие к script, он не работает, если сам script является символической ссылкой

Кроме того, в одном случае, о котором не упоминалось: при запуске script, передав его в качестве аргумента в оболочку (/bin/sh /path/to/myscript.sh), $0 не может использоваться в этом случае

Я посмотрел на mysql "двоичные файлы", многие из них на самом деле являются сценариями оболочки; и теперь я понимаю, почему они запрашивают параметр --basedir или должны быть запущены из определенного рабочего каталога; это потому, что нет хорошего решения для поиска целевого script

Ответ 7

Это то, что я сделал:

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

Ответ 8

Это также работает, хотя он не даст "истинный" путь, если это ссылка. Это проще, но менее точно.

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

Ответ 9

Попробуйте выполнить команду.

which scriptname

предоставит вам полное имя script вместе с его абсолютным путем

Ответ 10

Я обновил ответ Эдварда Штаудта, чтобы иметь дело с символическими ссылками абсолютного пути и с цепочками ссылок.

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

Ответ 11

Использование $_ предоставляет последнюю команду.

>source my_script

Работает, если я дважды выдаю команду:

>source my_script
>source my_script

Если я использую другую последовательность команд:

>who
>source my_script

Переменная $_ возвращает "who"

Ответ 12

Попробуйте использовать это:

dir = $(dirname $0)