Могу ли я получить абсолютный путь к текущему скрипту в KornShell? - PullRequest
21 голосов
/ 17 апреля 2009

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

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

Спасибо

Ответы [ 12 ]

27 голосов
/ 04 мая 2009

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

## __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 )
9 голосов
/ 31 июля 2013

В оболочке 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

Обратите внимание на последнюю строку там? Используйте $ _. По крайней мере, в Корне. YMMV in bash, csh и др ..

8 голосов
/ 07 февраля 2012

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

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

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

8 голосов
/ 17 апреля 2009

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

readlink -f "$0"
4 голосов
/ 25 августа 2011

Переменная $ 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
2 голосов
/ 11 июня 2010

Вот что я сделал:

if [[ $0 != "/"* ]]; then
  DIR=`pwd`/`dirname $0`
else
  DIR=`dirname $0`
fi
2 голосов
/ 03 марта 2010

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

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

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

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

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

1 голос
/ 07 декабря 2009

Попробуйте какую команду.

which scriptname

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

1 голос
/ 15 мая 2009

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

SCRIPT_PATH="$(whence ${0})"
0 голосов
/ 07 сентября 2017

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

>source my_script

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

>source my_script
>source my_script

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

>who
>source my_script

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

...