1. Опрятный
Я изучил почти все предложения, и вот одно из них, которое сработало для меня:
script_root=$(dirname $(readlink -f $0))
Работает, даже если скрипт связан с каталогом $PATH
.
Смотрите это в действии здесь: https://github.com/pendashteh/hcagent/blob/master/bin/hcagent
2. Самый крутой
# Copyright https://stackoverflow.com/a/13222994/257479
script_root=$(ls -l /proc/$$/fd | grep "255 ->" | sed -e 's/^.\+-> //')
Это фактически из другого ответа на этой самой странице, но я тоже добавляю его в свой ответ!
2. Самый надежный
В качестве альтернативы, в тех редких случаях, когда они не работали, вот пуленепробиваемый подход:
# Copyright http://stackoverflow.com/a/7400673/257479
myreadlink() { [ ! -h "$1" ] && echo "$1" || (local link="$(expr "$(command ls -ld -- "$1")" : '.*-> \(.*\)$')"; cd $(dirname $1); myreadlink "$link" | sed "s|^\([^/].*\)\$|$(dirname $1)/\1|"); }
whereis() { echo $1 | sed "s|^\([^/].*/.*\)|$(pwd)/\1|;s|^\([^/]*\)$|$(which -- $1)|;s|^$|$1|"; }
whereis_realpath() { local SCRIPT_PATH=$(whereis $1); myreadlink ${SCRIPT_PATH} | sed "s|^\([^/].*\)\$|$(dirname ${SCRIPT_PATH})/\1|"; }
script_root=$(dirname $(whereis_realpath "$0"))
Вы можете увидеть это в действии в taskrunner
источник: https://github.com/pendashteh/taskrunner/blob/master/bin/taskrunner
Надеюсь, это поможет кому-то там:)
Также, пожалуйста, оставьте его в качестве комментария, если он вам не подходит, и укажите вашу операционную систему и эмулятор. Спасибо!