
Я установил свои bash-скрипты в /usr/bin/app.sh
и/usr/bin/lib.sh
app.sh
включает
source "/usr/bin/lib.sh"
и lib.sh
включает в себя
if [ "/usr/bin/app.sh" == "$0"] ...
Когда я запускаю app.sh
из оболочки, этот тест не проходит, потому что $0
на самом деле /bin/app.sh
. В файловой системе /bin
есть символическая ссылка на/usr/bin
Какой лучший способ lib.sh
определить, включен ли он app.sh
(в отличие от other-app.sh
) таким образом, чтобы его не обманула среда? Я бы подумал, что абсолютные пути без символических ссылок справятся с этой задачей, но, видимо, нет.
решение1
Чтобы проверить, являются ли два файла одинаковыми, необходимо проверить номер индекса (инода), который отображается с помощью:
stat -L -c %i FilePath
Итак, ваш чек теперь будет выглядеть так:
if [ $(stat -L -c %i "/usr/bin/app.sh") == $(stat -L -c %i "$0") ] ...
Это работает независимо от каких-либо ссылок в пути к каталогу или даже символической или жесткой ссылки на сам файл.
Если быть совсем точным (спасибо @ilkkachu за указание на это), то вероятность того, что два разных файла с одинаковым именем могут иметь одинаковый inode в двух разных файловых системах, крайне мала. Чтобы этого избежать, включите в сравнение номер устройства:
if [ $(stat -L -c %d:%i "/usr/bin/app.sh") == $(stat -L -c %d:%i "$0") ] ...
решение2
readlink -f /path/to/whatever
укажет вам канонический путь (который будет /usr/bin/app.sh
в вашем примере).
канонизировать, следуя каждой символической ссылке в каждом компоненте данного имени рекурсивно; все компоненты, кроме последнего, должны существовать