Получить текущий каталог скриптов (чтобы я мог включать файлы без относительных путей и запускать скрипт из разных источников)

У меня есть следующая проблема: в моем сценарии оболочки есть что-то вроде:

mydir='' # config load source $mydir/config.sh .... execute various commands 

Мой скрипт помещен в мой пользовательский /home/bob/script.sh скажем, /home/bob/script.sh

Если я внутри /home/bob dir и запускаю ./script.sh все работает отлично.

Если я нахожусь снаружи и хочу использовать абсолютный путь /home/bob/script.sh файл config.sh не будет вызван должным образом.

Какую ценность я должен назначить $mydir , чтобы заставить скрипт работать со всех сторон без борьбы?

 mydir=$(which command?) 

PS: как бонус, пожалуйста, также предоставляйте альтернативу, если директория скрипта находится внутри $ PATH

4 Solutions collect form web for “Получить текущий каталог скриптов (чтобы я мог включать файлы без относительных путей и запускать скрипт из разных источников)”

Переменная $0 содержит путь к скрипту:

 $ cat ~/bin/foo.sh #!/bin/sh echo $0 $ ./bin/foo.sh ./bin/foo.sh $ foo.sh /home/terdon/bin/foo.sh $ cd ~/bin $ foo.sh ./foo.sh 

Как вы можете видеть, результат зависит от способа его вызова, но он всегда возвращает путь к скрипту относительно способа выполнения сценария. Поэтому вы можете:

 ## Set mydir to the directory containing the script ## The ${var%pattern} format will remove the shortest match of ## pattern from the end of the string. Here, it will remove the ## script's name,. leaving only the directory. mydir="${0%/*}" # config load source "$mydir"/config.sh 

Если каталог находится в вашей $PATH , все еще проще. Вы можете просто запустить source config.sh . По умолчанию source будет искать файлы в каталогах в $PATH и будет источник первого найденного:

 $ help source source: source filename [arguments] Execute commands from a file in the current shell. Read and execute commands from FILENAME in the current shell. The entries in $PATH are used to find the directory containing FILENAME. If any ARGUMENTS are supplied, they become the positional parameters when FILENAME is executed. 

Если вы уверены, что ваш config.sh уникален или, по крайней мере, он первый, найденный в $PATH , вы можете напрямую его загрузить. Однако я предлагаю вам не делать этого и придерживаться первого метода. Вы никогда не знаете, когда другой config.sh может быть в вашей $PATH .

Найдено решение:

 mydir=$(dirname "$0") 

С этим сценарий можно вызывать везде, без проблем.

Этот метод полезен только в сценарии bash .

Использование:

 mydir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" > /dev/null && pwd )" 

Как это работает:

BASH_SOURCE – это переменная массива, члены которой являются исходными именами файлов, в которых определены соответствующие имена функций оболочки в переменной массива FUNCNAME.

Итак, с:

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

вы переходите в каталог, где размещается скрипт.

Затем вывод cd отправляется в /dev/null , потому что иногда он печатает что-то в STDOUT. Например, если ваш CDPATH имеет .

и, наконец, он выполняет:

 pwd 

который получает текущее местоположение.

Источник :

https://stackoverflow.com/questions/59895/can-a-bash-script-tell-what-directory-its-stored-in?page=1&tab=oldest#tab-top

Попробуйте это проверить и проверить с помощью решения shellcheck :

 mydir="$(dirname "${0}")" source "${mydir}"/config.sh printf "read value of config_var is %s\n" "${config_var}" 

Тест:

 $ ls script.sh config.sh $ cat script.sh #!/bin/bash -- mydir="$(dirname "${0}")" source "${mydir}"/config.sh printf "read value of config_var is %s\n" "${config_var}" $ cat config.sh config_var=super_value $ mkdir "$(printf "\1\2\3\4\5\6\7\10\11\12\13\14\15\16\17\20\21\22\23\24\25\26\27\30\31\32\33\34\35\36\37\40\41\42\43\44\45\46\47testdir" "")" $ mv *.sh *testdir $ *testdir/script.sh read value of config_var is super_value 
  • Передать пароль для 7zip
  • Что требуется POSIX для цитирования здесь документов внутри подстановки команд?
  • grep script - выводит строки одновременно в эхо
  • Получение идентификатора родительского / дочернего процесса из определенного идентификатора процесса
  • Какую команду idempotent можно использовать, чтобы символическая ссылка указывала на каталог?
  • shell-скрипты все еще работают без #! (строка sha-bang)
  • Вставить текст в определенные строки файла? со специальными символами
  • Выполнить такую ​​же операцию для нескольких пар файлов с похожими именами
  • Приведение процесса к файловому дескриптору в переменную
  • Разместить файл доступа ht в webroot каждого скрипта bash каталога
  • Порядок обработки и печать файлов с помощью find
  • Linux и Unix - лучшая ОС в мире.