it-swarm-ru.tech

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

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

Я знаю о dirname $0 идиома, которая отлично работает, когда мой скрипт вызывается напрямую. К сожалению, есть желание иметь возможность создавать символические ссылки на эти сценарии из совершенно другого каталога и при этом работать с относительной логикой пути.

Пример общей структуры каталогов:

/
 |-usr/local/lib
 |  |-foo
 |  |  |-bin
 |  |  |  |-script.sh
 |  |  |-res
 |  |  |  |-resource_file.txt
 |-home/mike/bin
 |  |-link_to_script (symlink to /usr/local/lib/foo/bin/script.sh)

Как я могу надежно ссылаться /usr/local/lib/foo/res/resource_file.txt от script.sh вызван ли он /usr/local/lib/foo/bin/script.sh или ~mike/bin/link_to_script?

59
Mike Deck

Попробуйте это как универсальное решение:

DIR="$(cd "$(dirname "$0")" && pwd)"

В конкретном случае следующих символических ссылок вы также можете сделать это:

DIR="$(dirname "$(readlink -f "$0")")"
83
Caleb

одна линия:

cd $(dirname $([ -L $0 ] && readlink -f $0 || echo $0))
8
diyism

readlink -f не работает для меня, у меня есть эта ошибка:

readlink: illegal option -- f
usage: readlink [-n] [file ...]

Но это работает отлично:

DIR="$(dirname "$(readlink "$0")")"
echo $DIR
4
Kevin Campion

Одно небольшое дополнение к приведенному выше сценарию. Опция -P для pwd следует за символическими ссылками

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