it-swarm.com.ru

Как установить текущий рабочий каталог в каталог скрипта?

Я пишу сценарий Bash. Мне нужен текущий рабочий каталог, чтобы всегда быть каталогом, в котором находится скрипт.

Поведение по умолчанию таково, что текущим рабочим каталогом в сценарии является тот из командной консоли, из которой я его запускаю, но я не хочу этого поведения.

442
jameshfisher
#!/bin/bash
cd "$(dirname "$0")"
517
ndim

Следующее также работает:

cd "${0%/*}"

Синтаксис подробно описан в ответе this StackOverflow.

288
Paul Schulz

Попробуйте следующие простые однострочники:


Для всех UNIX/OSX/Linux

dir=$(cd -P -- "$(dirname -- "$0")" && pwd -P)

Примечание. Двойная тире (-) используется в командах для обозначения конца параметров команды, поэтому файлы, содержащие тире или другие специальные символы, не нарушают команду.


Для Linux, Mac и других * BSD:

cd "$(dirname "$(realpath "$0")")";

Примечание: realpath должен быть установлен в самом популярном дистрибутиве Linux по умолчанию (например, Ubuntu), но в некоторых он может отсутствовать, поэтому его нужно установить.

В противном случае вы можете попробовать что-то подобное (он будет использовать первый существующий инструмент):

cd "$(dirname "$(readlink -f "$0" || realpath "$0")")"

Для Linux:

cd "$(dirname "$(readlink -f "$0")")"

Использование GNU readlink на * BSD/Mac:

cd "$(dirname "$(greadlink -f "$0")")"

Примечание. Вам необходимо установить coreutils (например, 1. Установить Homebrew , 2. brew install coreutils).


В bash

В bash вы можете использовать Расширения параметров для достижения этого, например:

cd "${0%/*}"

но это не работает, если скрипт запускается из той же директории.

В качестве альтернативы вы можете определить следующую функцию в bash:

realpath () {
  [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}"
}

Эта функция принимает 1 аргумент. Если аргумент уже имеет абсолютный путь, выведите его как есть, в противном случае выведите переменную $PWD + аргумент имени файла (без префикса ./).

или вот версия, взятая из файла Debian .bashrc:

function realpath()
{
    [email protected]
    if [ -d "$f" ]; then
        base=""
        dir="$f"
    else
        base="/$(basename "$f")"
        dir=$(dirname "$f")
    fi
    dir=$(cd "$dir" && /bin/pwd)
    echo "$dir$base"
}

Связанные с:

Смотрите также:

Как я могу получить поведение readlink -f GNU на Mac?

153
kenorb
cd "$(dirname "${BASH_SOURCE[0]}")"

Это просто. Оно работает.

59
Dan Moulding

Принятый ответ хорошо работает для сценариев, которые не были символическими ссылками где-либо еще, например, в $PATH.

#!/bin/bash
cd "$(dirname "$0")"

Однако, если скрипт запускается по символической ссылке,

ln -sv ~/project/script.sh ~/bin/; 
~/bin/script.sh

Это перейдет в каталог ~/bin/, а не в каталог ~/project/, что, вероятно, сломает ваш скрипт, если целью cd является включение зависимостей относительно ~/project/

Безопасный ответ по символической ссылке ниже:

#!/bin/bash
cd "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")"

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

Кавычки необходимы для поддержки файловых путей, которые потенциально могут содержать пробелы (плохая практика, но небезопасно предполагать, что это не так)

5
James McGuigan

Этот скрипт, кажется, работает для меня:

#!/bin/bash
mypath=`realpath $0`
cd `dirname $mypath`
pwd

Командная строка pwd отражает местоположение скрипта как текущего рабочего каталога, независимо от того, откуда я его запускаю.

2
Amardeep AC9MF

Получить реальный путь к вашему сценарию

if [ -L $0 ] ; then
    ME=$(readlink $0)
else
    ME=$0
fi
DIR=$(dirname $ME)

(Это ответ на тот же мой вопрос здесь: Получить имя каталога, в котором выполняется скрипт )

1
rodnower
cd "`dirname $(readlink -f ${0})`"
1
user742030