У меня есть файл сценария bash, который помещен в какой-то каталог, добавленный в $ PATH, чтобы я мог вызывать сценарий из любого каталога.
В том же каталоге, что и скрипт, находится другой текстовый файл. Интересно, как ссылаться на текстовый файл в скрипте?
Например, если скрипт просто выводит содержимое текстового файла, cat textfile
работать не будет, поскольку при вызове скрипта из другого каталога текстовый файл не найден.
Ответы:
Они должны работать одинаково, если нет символических ссылок (в расширении пути или в самом скрипте):
MYDIR="$(dirname "$(realpath "$0")")"
MYDIR="$(dirname "$(which "$0")")"
Двухэтапная версия любого из вышеперечисленного:
MYSELF="$(realpath "$0")"
MYDIR="${MYSELF%/*}"
Если на пути к вашему сценарию есть символическая ссылка, вы
which
получите ответ, не включающий разрешение этой ссылки. Еслиrealpath
по умолчанию не установлен в вашей системе, вы можете найти его здесь .[РЕДАКТИРОВАТЬ]: Поскольку кажется, что не
realpath
имеет никаких преимуществ по сравнению сreadlink -f
предложенным Калебом , вероятно, лучше использовать последний. Мои временные тесты показывают, что это на самом деле быстрее.источник
realpath
в вашей системе? (Для тех, у кого его нет, вы можете использоватьreadlink -f
realpath
восходит к тому времениreadlink -f
(и дажеreadlink
IIRC), который был в GNU coreutils (было несколько подобных инструментов. Вreadlink -f
конечном итоге он стал стандартом де-факто);realpath
хранится только для совместимости со скриптами, которые все еще используют его.$(dirname "$(which "$0")")
перед тем,$(dirname $0)
гдеwhich
больше нет? Разве это не то же самое?readlink -f
похоже, не работает на Mac OS X 10.11.6, ноrealpath
работает из коробки.Мои системы не имеют,
realpath
как предложено rozcietrzewiacz .Вы можете сделать это с помощью
readlink
команды. Преимущество использования этого по сравнению с синтаксическим анализомwhich
или другими решениями состоит в том, что даже если часть пути или имя исполняемого файла была символической ссылкой, вы сможете найти каталог, где находился фактический файл.Ваш текстовый файл может быть затем прочитан в переменную, как это:
источник
which
предложение. Обычное решение для этого включает в себя либо просто,dirname
либо комбинациюcd
иpwd
в подоболочке. Readlink имеет преимущество здесь.realpath
вreadlink -f
любом случае, похоже, просто обертка .realpath
отличается отreadlink -f
. Я могу только видеть, что это дает мне те же результаты (в отличие отwhich
).readlink -f
(из GNU coreutils) НЕ требуется, чтобы существовал последний элемент путиreadlink -e
, но он не поддерживаетсяbusybox readlink
, что имитирует поведение-e
их-f
опции.$0
в скрипте будет полный путь к скрипту, и онdirname
будет принимать полный путь и даст вам только каталог, так что вы можете сделать это для cat textfile:источник
realpath $0
, вы ошибаетесь, говоря, что «$0
в скрипте будет полный путь к скрипту».$0
это команда , как он был запущен, который может быть , например../script.sh
.$(dirname "$0")
возвращает относительный путь к сценарию, как часть вызванной команды, а не абсолютный путь. Это может привести к проблемам в скриптах, которые изменяют каталоги во время работы.Вы можете поместить это вверху вашего скрипта:
Источник: http://mywiki.wooledge.org/BashFAQ/028
источник
Я пробовал это, и RealPath не работал для меня. Решение, которое я выбрал:
Который до сих пор хорошо работал. Я хотел бы знать, есть ли потенциальные проблемы с подходом.
источник
SCRIPT_DIR="$( cd "$(dirname "$( readlink -f ${BASH_SOURCE[0]} )")" >/dev/null 2>&1 && pwd)"
Я использую:
Что POSIX и должен работать до тех пор , как имя папки из
$0
не заканчивается символом новой строки, не-
и$CDPATH
не установлен (и , возможно , несколько других случаев угловыми , если сценарий не смотрел, в$PATH
).источник
Я всегда использую,
which
чтобы найти полный путь к исполняемому файлу из PATH. Например:which python
Если вы объедините это с
dirname
командой, то получите:источник