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

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

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

Ответ 1

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

Ответ 2

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

cd "${0%/*}"

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

Ответ 3

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


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

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

удар

dir=$(cd -P -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)

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

Примечание. В Bash используйте ${BASH_SOURCE[0]} $0, в противном случае путь может оборваться при его поиске (source/.).


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

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

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

Примечание. Если вы используете Bash, используйте ${BASH_SOURCE[0]} в пользу $0, в противном случае путь может оборваться при его поиске (source/.).

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

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 вы можете использовать расширения параметров для достижения этой цели, например:

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"
}

Связанные с:

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

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

Ответ 4

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

Это легко. Оно работает.

Ответ 5

Принятый ответ хорошо работает для сценариев, которые не были символическими ссылками где-либо еще, например, в $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 необходима для разрешения абсолютного пути к файлу с потенциально символической ссылкой.

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

Ответ 6

Этот script, похоже, работает для меня:

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

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

Ответ 8

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

Ответ 9

echo $PWD | rev | cut -d'/' -f1 | rev

Ответ 10

echo $PWD

PWD - это переменная среды.

Ответ 11

Если вам просто нужно распечатать текущий рабочий каталог, вы можете следовать этому.

$ vim test

#!/bin/bash
pwd
:wq to save the test file.

Предоставить разрешение на выполнение:

chmod u+x test

Затем выполните script на ./test, после чего вы увидите текущий рабочий каталог.