Как bash script знает каталог, в котором он установлен, когда он создан. оператор?
Что я хотел бы сделать, так это включить настройки из файла в текущую интерактивную оболочку bash следующим образом:
$./path/to/some/dir/.settings
Проблема заключается в том, что .settings script также необходимо использовать ".". для включения других файлов:
..extra_settings
Как ссылаться на относительный путь для .extra_settings в файле .settings? Эти два файла всегда хранятся в одном каталоге, но путь к этому каталогу будет отличаться в зависимости от того, где эти файлы были установлены.
Оператор всегда знает путь /path/to/some/dir/, как показано выше. Как файл .settings знает каталог, в котором он установлен? Я бы предпочел не иметь процесс установки, который записывает имя установленного каталога.
Ответы
Ответ 1
Я считаю, что $(dirname "$BASH_SOURCE")
будет делать то, что вы хотите, если файл, который вы используете, не символическая ссылка.
Если файл, который вы используете, может быть символической ссылкой, вы можете сделать что-то вроде следующего, чтобы получить настоящий каталог:
PRG="$BASH_SOURCE"
progname=`basename "$BASH_SOURCE"`
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
dir=$(dirname "$PRG")
Ответ 2
Вот что может быть элегантным решением:
script_dir=$( cd $( dirname "${BASH_SOURCE[0]}" ) && pwd )
Однако это не будет работать при поиске ссылок. В этом случае можно сделать
script_dir=$( readlink -f $( readlink "${BASH_SOURCE[0]}" )
Будьте уверены, что массивы типа ${array[x]}
не совместимы с POSIX. Разумеется, массив BASH_SOURCE
доступен только в Bash.
Ответ 3
Разный подход к проблеме - если вы используете "." для установки переменных среды другой стандартный способ сделать это состоит в том, чтобы иметь команды настройки параметров эхо-команды script, например:
# settings.sh
echo export CLASSPATH=${CLASSPATH}:/foo/bar
то eval вывод:
eval $(/path/to/settings.sh)
Как пакеты, такие как modules работают. Этот способ также облегчает поддержку оболочек, полученных из sh (X=...; export X
) и csh (setenv X ...
)
Ответ 4
Я попытался возиться с вариантами $(dirname $0), но он терпит неудачу, когда файл .settings включен в ".". Если бы я исполнял файл .settings, а не включал его, это решение сработало бы. Вместо этого $(dirname $0) всегда возвращает ".", Что означает текущий каталог. Это происходит при выполнении примерно так:
$cd/
$./some/path/.settings
Ответ 5
Такие работы. Он работает в том смысле, что вы можете использовать синтаксис $(dirname $0) в файле .settings для определения своего дома, поскольку вы выполняете этот script в новой оболочке. Однако он добавляет дополнительный слой свертки, где вам нужно изменить строки, такие как:
export MYDATE=$(date)
к
echo "export MYDATE=\$(date)"
Возможно, это единственный способ?