Как получить путь к каталогу, в котором находится скрипт Bash , внутри этого скрипта?
Например, скажем, я хочу используйте скрипт Bash в качестве средства запуска для другого приложения. Я хочу изменить рабочий каталог на тот, где находится скрипт Bash, чтобы я мог работать с файлами в этом каталоге, например так:
$ ./application
#!/bin/bash
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
полезная острота, которая даст Вам полное имя каталога сценария, неважно, откуда это называют.
Это будет работать пока последний компонент пути, используемого, чтобы найти, что сценарий не является символьной ссылкой (ссылки каталога в порядке). Если Вы также хотите разрешить какие-либо ссылки на сам сценарий, Вам нужно многострочное решение:
#!/bin/bash
SOURCE="${BASH_SOURCE[0]}"
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"
SOURCE="$(readlink "$SOURCE")"
[[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
done
DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"
Этот последний будет работать с любой комбинацией псевдонимов, source
, bash -c
, символьные ссылки, и т.д.
Остерегаются: если Вы cd
к различному каталогу прежде, чем выполнить этот отрывок, результат может быть неправильным!
кроме того, не упустите $CDPATH
глюки , и выходные побочные эффекты stderr, если пользователь энергично переопределил CD для перенаправления вывода к stderr вместо этого (включая escape-последовательности, такой, звоня update_terminal_cwd >&2
на Mac). При добавлении >/dev/null 2>&1
в конце Вашего cd
команда будет заботиться об обеих возможностях.
, Чтобы понять, как это работает, попытайтесь выполнить это больше подробной формы:
#!/bin/bash
SOURCE="${BASH_SOURCE[0]}"
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
TARGET="$(readlink "$SOURCE")"
if [[ $TARGET == /* ]]; then
echo "SOURCE '$SOURCE' is an absolute symlink to '$TARGET'"
SOURCE="$TARGET"
else
DIR="$( dirname "$SOURCE" )"
echo "SOURCE '$SOURCE' is a relative symlink to '$TARGET' (relative to '$DIR')"
SOURCE="$DIR/$TARGET" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
fi
done
echo "SOURCE is '$SOURCE'"
RDIR="$( dirname "$SOURCE" )"
DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"
if [ "$DIR" != "$RDIR" ]; then
echo "DIR '$RDIR' resolves to '$DIR'"
fi
echo "DIR is '$DIR'"
И это распечатает что-то как:
SOURCE './scriptdir.sh' is a relative symlink to 'sym2/scriptdir.sh' (relative to '.')
SOURCE is './sym2/scriptdir.sh'
DIR './sym2' resolves to '/home/ubuntu/dotfiles/fo fo/real/real1/real2'
DIR is '/home/ubuntu/dotfiles/fo fo/real/real1/real2'
Я обычно делаю:
LIBDIR=$(dirname "$(readlink -f "$(type -P [110] || echo [110])")")
source $LIBDIR/lib.sh
Я хочу удостовериться, что сценарий работает в его каталоге. Так
cd $(dirname $(which [110]) )
После этого если Вы действительно хотите знать, куда Вы работают затем, выполняет команду ниже.
DIR=$(/usr/bin/pwd)
Используйте dirname "[112]"
:
#!/bin/bash
echo "The script you are running has basename `basename "[110]"`, dirname `dirname "[110]"`"
echo "The present working directory is `pwd`"
использование pwd
один не будет работать, если Вы не выполните сценарий из каталога, это содержится в.
[matt@server1 ~]$ pwd
/home/matt
[matt@server1 ~]$ ./test2.sh
The script you are running has basename test2.sh, dirname .
The present working directory is /home/matt
[matt@server1 ~]$ cd /tmp
[matt@server1 tmp]$ ~/test2.sh
The script you are running has basename test2.sh, dirname /home/matt
The present working directory is /tmp
pushd . > /dev/null
SCRIPT_PATH="${BASH_SOURCE[0]}"
if ([ -h "${SCRIPT_PATH}" ]); then
while([ -h "${SCRIPT_PATH}" ]); do cd `dirname "$SCRIPT_PATH"`;
SCRIPT_PATH=`readlink "${SCRIPT_PATH}"`; done
fi
cd `dirname ${SCRIPT_PATH}` > /dev/null
SCRIPT_PATH=`pwd`;
popd > /dev/null
Работы для всех версий, включая [1 125]
.
(точечный) оператор. [114]
изменяется от вызывающей стороны. "./script"
"/full/path/to/script"
"/some/path/../../another/path/script"
"./some/folder/script"
, С другой стороны, если сам сценарий удара относительная символьная ссылка , Вы хотите следовать за ним и возвратить полный путь связанного - к сценарию:
pushd . > /dev/null
SCRIPT_PATH="${BASH_SOURCE[0]}";
if ([ -h "${SCRIPT_PATH}" ]) then
while([ -h "${SCRIPT_PATH}" ]) do cd `dirname "$SCRIPT_PATH"`; SCRIPT_PATH=`readlink "${SCRIPT_PATH}"`; done
fi
cd `dirname ${SCRIPT_PATH}` > /dev/null
SCRIPT_PATH=`pwd`;
popd > /dev/null
SCRIPT_PATH
дан в полном пути, неважно, как это называют.
Просто удостоверяются, что Вы определяете местоположение этого в начале сценария.
Этот Копилефт комментария и кода, выбираемая лицензия под GPL2.0 или позже или CC-SA 3.0 (Доля CreativeCommons Одинаково) или позже. (c) 2008.Все права защищены. Никакая гарантия любого вида. Вас предупредили.
http://www.gnu.org/licenses/gpl-2.0.txt
http://creativecommons.org/licenses/by-sa/3.0/
18eedfe1c99df68dc94d4a94712a71aaa8e1e9e36cacf421b9463dd2bbaa02906d0d6656
Можно использовать $BASH_SOURCE
#!/bin/bash
scriptdir=`dirname "$BASH_SOURCE"`
Примечание, что необходимо использовать #!/bin/bash и не #!/bin/sh, так как это - расширение удара
Это - конкретный Linux, но Вы могли использовать:
SELF=$(readlink /proc/$/fd/255)
pwd
может использоваться, чтобы найти, что текущий рабочий каталог, и dirname
находит каталог конкретного файла (команда, которая была выполнена, [114]
, таким образом dirname [115]
должен дать Вам каталог текущего сценария).
Однако dirname
дает точно часть каталога имени файла, которое более вероятно, чем не будет относительно текущего рабочего каталога. Если Ваш сценарий должен изменить каталог по некоторым причинам, то вывод от dirname
становится бессмысленным.
я предлагаю следующее:
#!/bin/bash
reldir=`dirname [110]`
cd $reldir
directory=`pwd`
echo "Directory is $directory"
Таким образом, Вы получаете абсолют, скорее тогда относительный каталог.
, Так как сценарий будет выполнен в отдельном экземпляре удара, нет никакой потребности восстановить рабочий каталог впоследствии, но если Вы действительно хотите возвратиться в своем сценарии по некоторым причинам, можно легко присвоить значение pwd
к переменной перед изменением каталога для будущего использования.
, Хотя всего
cd `dirname [111]`
решает определенный сценарий в вопросе, я нахожу наличие полного пути к более более полезному обычно.
Я не думаю, что это столь легко, как другие разобрали его, чтобы быть. pwd не работает, поскольку текущий dir является не обязательно каталогом со сценарием. 0$ не всегда имеют информацию также. Рассмотрите следующие три способа вызвать сценарий.
./script
/usr/bin/script
script
первыми и третьими способами 0$ не имеют информации о полном пути Во втором, и третье, pwd не работают. Единственный способ получить dir третьим путем состоял бы в том, чтобы пробежать путь и найти файл с корректным соответствием. В основном код должен был бы восстановить то, что делает ОС.
Один способ сделать, что Вы спрашиваете, был бы только к hardcode данные в/usr/share dir и сослался бы на него полным путем. Данные shoudn't быть в/usr/bin dir так или иначе, таким образом, это, вероятно, нужно.
Это работает в ударе 3.2:
path="$( dirname "$( which "[110]" )" )"
Вот пример его использования:
Говорят, что Вы имеете ~ / мусорное ведро каталог, который находится в Вашем $PATH . У Вас есть сценарий внутренняя часть этот каталог. Это источник сценарий ~/bin/lib/b с. Вы знаете, где включенный сценарий относительно исходного (подкаталог lib ), но не, где это относительно текущего каталога пользователя.
Это решено следующим (в А ):
source "$( dirname "$( which "[111]" )" )/lib/B"
не имеет значения, где пользователь или как он называет сценарий, это будет всегда работать.
Хм, если в базовом имени пути & dirname просто не собираются сокращать его и идут, путь тверд (что, если родитель не экспортировал ПУТЬ!). Однако оболочка должна иметь открытый дескриптор к своему сценарию, и в ударе дескриптор является работами № 255.
SELF=`readlink /proc/$/fd/255`
для меня.
source <script>
иbash <script>
:DIR="$(cd -P "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
. – Dan Moulding 20.10.2011, 05:54cd
печать что-то к STDOUT! Например, если Ваш$CDPATH
имеет.
. Для покрытия этого случая используйтеDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" > /dev/null && pwd )"
– user716468 03.02.2013, 15:33This means that we need two separate NSPersistentStoreCoordinators, each of them having it's own NSManagedObjectContext.
– Arek Holko 14.10.2013, 10:31