LINUX.ORG.RU

Путь ко включаемому файлу


0

0

Вопрос про подключаемые файлы в с-приограммах и bash-скриптах.
Когда мы делаем в скрипте /1/2/3/скрипт так:
. ./xxx.cfg
или в какой-нибудь с-программе так:
#include "./xxx.h",
то . - это "текущий каталог".
Так вот, текущий какталог - это понятие растяжимое.
Если я вызываю скрипт, содержащий указанное включение, как
/4/5$ /1/2/3/скрипт
или
/1/2/3$ скрипт -
то точка имеет разные значения.
То же самое, если речь идёт о #include "../xxx.h": две точки
отсчитываются относительно чего? Насколько я могу судить из своего
опыта, разные компилляторы могут расценивать относительные пути
по-разному.
В общем, вопрос: можно ли как-нибудь указывать в относительных путях
конкретно: относительность отсчитывается от положения файла, содержащего
относительный путь, или от текущего каталога?

>> То же самое, если речь идёт о #include "../xxx.h": две точки отсчитываются относительно чего?

Относительно расположения файла, в котором встретилась директива #include.

>> Насколько я могу судить из своего опыта, разные компилляторы могут расценивать относительные пути по-разному.

Не знаю на каких компиляторах вы экспериментировали, но GCC, ICC и MSVC++ смотрят относительно файла в котором #include. По крайней мере по умолчанию.

Deleted
()

В случае bash-скрптов, "./xxx.cfg" - это относительно текущей рабочей директории, которая выставляется с помощью chdir(2) (вызывается встроенной в шелл командой cd).

Deleted
()
Ответ на: комментарий от Deleted

> Не знаю на каких компиляторах вы экспериментировали, но GCC, ICC и
> MSVC++ смотрят относительно файла в котором #include.

И правильно делают. Вроде бы не так было в каком-то из старых
борландовских (досовских), хотя точно не помню. Но вроде было :-)

А в скриптах - просто хотелось кроме . ./xxx, которое относительно
текущего рабочего каталога, что-то вроде . %/xxx, где % - относительно
текущего файла. Чтобы не надо было перед вызовом скрипта cd делать.
Чтобы он сам по себе всегда работал :-)

sergey_feo
() автор топика
Ответ на: комментарий от sergey_feo

>> А в скриптах - просто хотелось кроме . ./xxx, которое относительно 
>> текущего рабочего каталога, что-то вроде . %/xxx, где % -
>> относительно текущего файла. Чтобы не надо было перед вызовом скрипта
>> cd делать. Чтобы он сам по себе всегда работал :-)

Я в таких случаях использую примерно такой кусок кода:

if echo -n "${0}" | grep "^/" > /dev/null; then
	BASE_PATH=$( dirname "${0}" )
else
	BASE_PATH=$( dirname "$( pwd )/${0}" )
fi

. "${BASE_PATH}/somefile.sh"

Deleted
()
Ответ на: комментарий от sergey_feo

>> Кстати, не лучше ли строку 4 дополнить вот так: 
>> BASE_PATH=$( dirname "$( pwd )/${0:1}" ) ? 

Тогда скрипт будет работать неправильно, если его запустить так:

sh dir/script.sh

Deleted
()
Ответ на: комментарий от Deleted

Просто хотелось абсолютный путь получить, без фрагментов вида что-то/./что-то
или
что-то/../что-то
Но что-то путаюсь я в таких вещах :-)

Кстати, рыл-рыл, но так и не нарыл простой команды, делающей абсолютный
путь из относительного. Неужели не существует маленькой программки на
основе функции realpath()? Понятно, что написать её можно в 3 минуты, но
должна же быть стандартная, чтобы скрипты были чуть-чуть переносимы.

sergey_feo
() автор топика
Ответ на: комментарий от sergey_feo

>> Кстати, рыл-рыл, но так и не нарыл простой команды, делающей абсолютный 
>> путь из относительного. Неужели не существует маленькой программки на 
>> основе функции realpath()? Понятно, что написать её можно в 3 минуты, но 
>> должна же быть стандартная, чтобы скрипты были чуть-чуть переносимы.

Программа есть, но по умолчанию в дистрибутивах она стоит редко:

[I] app-admin/realpath
     Homepage:            http://packages.debian.org/unstable/utils/realpath
     Description:         Return the canonicalized absolute pathname

Deleted
()
Ответ на: комментарий от Deleted

В описании этой программы замечено, что она делает примерно то же самое, что и readlink -f.
Соответственно, скрипт можно упростить до:
BASE_PATH=$( dirname $( readlink -f "${0}" ) )
Если я опять ничего не напутал :-)

sergey_feo
() автор топика
Ответ на: комментарий от sergey_feo

>> BASE_PATH=$( dirname $( readlink -f "${0}" ) )

Работает =). /me пошёл исправлять свои скрипты.

Deleted
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.