Перейти к содержимому

Ld library path что это

  • автор:

Как правильно использовать LD_LIBRARY_PATH?

Решил на выходных повтыкать в одну игру с gog, а там в start.sh есть такой кусок:

# Actions run_game() < echo "Running $" export LD_LIBRARY_PATH="$CURRENT_DIR/game:$CURRENT_DIR/lib" local bin_name="SPAZ" cd game ./$bin_name > 

в таком виде при запуске этого скрипта я получаю:

Alert: Error Unable to initialize OpenGL. (Error: Failed loading libGL.so.1) Exiting 

но если закоментить

export LD_LIBRARY_PATH="$CURRENT_DIR/game:$CURRENT_DIR/lib" 

то игра стартует. Но тут мне стало просто интересно, что это за переменная такая, зачем её тут вставили и почему у меня она не работает\работает не так как надо. Смотрел тут пишут, что эту переменную лучше использовать только для дебага. Посмотрел у меня она по-умолчанию пуста. Попробовал прописывать разные пути, не вышло. В общем сам разобраться что к чему не смог, потому пришёл спросить здесь. На всякий случай дистр — gentoo.

flyshoot
07.10.16 17:37:16 MSK

Для чего используется LD_LIBRARY_PATH?

Прежде чем узнать LD_LIBRARY PATH, вы должны иметь представление о переменных среды. Но если вы не знаете, то не волнуйтесь, я объясню, что это такое. Переменные, значение которых определяется операционной системой или возможностями микрослужбы, называются переменными среды. Переменная среды – это динамически определяемое значение, которое может влиять на поведение запущенных компьютерных процессов. Процесс выполняется в компоненте среды процесса.

Сначала переменные среды были разработаны для UNIX, но теперь эти переменные есть и в Windows, и в Linux. Когда какой-либо процесс создается, он наследует копию среды выполнения своего родителя, за исключением явных изменений, сделанных родителем при создании дочернего процесса по умолчанию. Пара имя/значение составляет переменную среды, и любое их количество может быть сгенерировано и использовано в любое время. Обычно в именах переменных среды используются заглавные буквы. Это помогает отличать переменные среды от других типов имен в программном коде в целом. В операционной системе Unix переменные среды чувствительны к регистру, но не в DOS, OS/2 или Windows.

LD_LIBRARY также является переменной среды операционной системы UNIX/Linux; в этой статье мы подробно обсудим эту переменную среды.

Использование переменной LD_LIBRARY_PATH

В системе UNIX/Linux LD_LIBRARY_PATH указывает загрузчику динамической компоновки, небольшой программе, которая запускает все ваши приложения, чтобы определить, где искать динамические общие библиотеки, с которыми было связано приложение. Двоеточие (:) отделяет список каталогов, и этот список проверяется даже перед встроенными путями/путями поиска и обычными местоположениями, такими как (/lib, /usr/lib..).

Некоторые другие варианты использования LD_LIBRARY_PATH:

Проблема с LD_LIBRARY_PATH

Это очень полезно, пока вы не попытаетесь использовать его для решения своих проблем. Эта строка кажется странной, но это то, что происходит на самом деле, когда вы пытаетесь применить ее в пользовательской/системной среде, сценарий ухудшается, и все переменные среды начинают зависеть от нее, и она падает, так как не может справиться со всеми задачами!

Некоторые проблемы, возникающие при использовании LD_LIBRARY_PATH:

Безопасность: каталоги LD_LIBRARY_PATH проверяются в первую очередь, прежде чем их фактическое местоположение. Этот подход может быть использован злоумышленником, чтобы заставить ваше приложение запускать вредоносную версию общей библиотеки. Это одна из причин, по которой исполняемые файлы setuid/setgid игнорируют эту переменную.

Производительность: загрузчик ссылок должен просматривать все предоставленные каталоги, пока не найдет общие библиотеки (связанные с приложением). Следовательно, это приведет к открытию нескольких системных вызовов и их сбою с ENOENT «нет такого файла или каталога». Если указанный путь имеет много каталогов, это займет много времени, и вы можете проверить это во время запуска вашего приложения. В результате это приведет к замедлению работы всей системы.

Несогласованность. Наиболее распространенная проблема, связанная с использованием LD_LIBRARY_PATH, — несогласованность. LD_LIBRARY_PATH заставляет программу загружать разделяемую библиотеку, с которой она не была связана, что, безусловно, несовместимо с исходной версией. Это может быть очень очевидным, например, при сбое приложения, или может привести к неправильным результатам, если подобранная библиотека не совсем соответствует функциональности исходной версии. Это будет сложно отлаживать последнее, особенно.

Решение

Лучшее решение — чем меньше вы его используете, тем меньше проблем возникнет. На самом деле старайтесь избегать использования LD_LIBRARY_PATH:

Как избежать LD_LIBRARY_PATH:

Укажите правильное расположение разделяемой библиотеки. При компиляции приложения вам необходимо указать точное расположение разделяемых библиотек и указать путь в параметре компоновщика «-rpath», чтобы сообщить компоновщику о включении их в ваш путь запуска исполняемого файла или вы можете использовать переменную LD_RUN_PATH для указания нескольких путей

Инструмент для устранения проблемы: для исправления/изменения пути выполнения двоичного исполняемого файла доступны программы, такие как chrpath под Linux. Проблема в том, что исполняемое пространство, которое несет эту информацию (то есть строку пути), нельзя расширить, т. е. вы можете только переписать существующий путь.

Не помещайте LD_LIBRARY_PATH В ПРОФИЛЬ ПОЛЬЗОВАТЕЛЯ: Установив LD_LIBRARY_PATH в профиле пользователя, вы создадите себе проблемы, поэтому избегайте этого.

Не помещайте LD_LIBRARY_PATH В ПРОФИЛЬ СИСТЕМЫ. Некоторые независимые поставщики программного обеспечения предоставляют программное обеспечение, которое автоматически вставляет глобальные настройки LD LIBRARY PATH в системные профили во время установки или даже предлагает сделать это пользователю. Просто скажи нет! Попробуйте решить проблему другим способом, например, написав сценарий-оболочку, или попросите поставщика исправить ее.

LD_LIBRARY_PATH полезен, если используется для трех применений, которые упомянуты в разделе об использовании, но старайтесь использовать его как можно реже, чтобы защитить себя от неприятностей.

Сохранение переменной LD_LIBRARY_PATH в Linux

@Mike релог — это exit, закрытие терминала и открытие его снова, новое подключение по ssh. Пробовал прописывать и в $HOME/.bashrc и в $HOME/.bash_ profile — безрезультатно, переменная пустая при следующем входе в истему.

13 мар 2019 в 6:42

А у пользователя какой shell стоит ? Может не bash и тогда у него свои файлы старта сеанса. Для bash .bashrc или .bash_profile должны помогать. Можете в них для проверки какой нибудь echo написать, убедится что при входе пользователя строка эта будет выведена на экран (см. на пользователя в /etc/passwd). И вы же под $HOME точно домашний каталог нужного пользователя подразумевали (там же в passwd проверьте что это он)

13 мар 2019 в 6:53

@Mike ага, вот где собака зарыта. у рута bin/bash, а у этого пользователя оказалось /bin/sh. Огромное спасибо! Тогда вытекающий вопрос: где лежат аналогичные файлы для /bin/sh или как сменить пользователю оболочку и какие последствия это может повлечь?

13 мар 2019 в 7:00

/bin/sh скорее всего ссылка на какой нибудь другой shell (посмотрите в /bin не является ли он ссылкой). просто sh обычно не используется. но если это он, то $HOME/.profile (кстати он для многих оболочек может быть рабочим). Менять шелл можно с помощью chsh linux.die.net/man/1/chsh или просто поправьте в /etc/passwd. Последствий обычно никаких. Если сложных не bash скриптов тот пользовтель не писал (что очень вряд ли, учитывая что вы ранее не знали какой у него шелл 🙂 )

13 мар 2019 в 7:03

Хм. не знал такой особенности bash. Многие программы в unix ведут себя так, как называются. Для многих операций делается одна программа и кладутся ссылки на нее. Видимо bash пользуется той же техникой и меняет свое поведение в зависимости от того как вызван. например начинает эмулировать поведение стандартного sh (это только предположение, но думаю правильное)

Ld library path что это

В прошлый раз мы с Вами обнаружили, что запуск программ, скомпилированных вместе с динамическими библиотеками, вызывает ошибку:

dron:~# ./rezultdyn ./rezultdyn: error in loading shared libraries: libfsdyn.so: cannot open shared object file: No such file or directorydron:/#

Это сообщение выдает загрузчик динамических библиотек(динамический линковщик — dynamic linker), который в нашем случае не может обнаружить библиотеку libfsdyn.so. Для настройки динамического линковщика существует ряд программ.

Первая программа называется ldd. Она выдает на экран список динамических библиотек используемых в программе и их местоположение. В качестве параметра ей сообщается название обследуемой программы. Давайте попробуем использовать ее для нашей программы rezultdyn:

dron:~# ldd rezultdyn libfsdyn.so => not found libc.so.6 => /lib/libc.so.6 (0x40016000) /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000) dron:~#
  • libc.so.6 — стандартную библиотеку функций языка C++.
  • ld-linux.so.2 — библиотеку динамической линковки программ ELF формата.
  • libfsdyn.so — нашу динамическую библиотеку функций.

Нашу библиотеку она найти не может. И правильно! Динамический линковщик ищет библиотеки только в известных ему каталогах, а каталог нашей программы ему явно не известен.

Для того, чтобы добавить нашу директорию с библиотекой в список известных директорий надо подредактировать файл /etc/ld.so.conf. Например, у меня этот файл состоит из таких строк:

dron:~# cat /etc/ld.so.conf /usr/X11R6/lib /usr/i386-slackware-linux/lib /usr/i386-slackware-linux-gnulibc1/lib /usr/i386-slackware-linux-gnuaout/lib dron:~#

Во всех этих директории хранятся всеми используемые библиотеки. В этом списке нет лишь одной директории — /lib, которая сама по себе не нуждается в описании, так как она является главной. Получается, что наша библиотека станет «заметной», если поместить ее в один их этих каталогов, либо отдельно описать в отдельном каталоге. Давайте для теста опишем, добавим строку в конец файла ld.so.conf:

/root

У меня этот файл валяется в домашнем каталога пользователя root, у Вас он может быть в другом месте. Теперь после этого динамический линковщик будет знать где можно найти наш файл, но после изменения конфигурационного файла ld.so.conf необходимо, чтобы система перечитала настройки заново. Это делает программа ldconfig. Пробуем запустить нашу программу:

dron:~# ldconfig dron:~# ./rezultdyn f1() = 25 f2() = 10 dron:~#

Как видите все заработало 🙂 Если теперь Вы удалите добавленную нами строку и снова запустите ldconfig, то данные о расположении нашей библиотеки исчезнут и будет появляться таже самая ошибка.

Но описанный метод влияет на всю систему в целом и требует доступа администратора системы, т.е. root. А если Вы простой пользователь без сверх возможностей ?!

Для такого случая есть другое безболезненное решение. Это использование специальной переменной среды LD_LIBRARY_PATH, в которой перечисляются все каталоги содержащие пользовательские динамические библиотеки. Для того, чтобы установить эту переменную в командной среде bash надо набрать всего несколько команд. Для начала посмотрим есть ли у нас такая переменная среды:

dron:~# echo $LD_LIBRARY_PATH

У меня в ответ выводится пустая строка, означающая, что такой переменной среды нет. Устанавливается она следующим образом:

dron:~# LD_LIBRARY_PATH=/root dron:~# export LD_LIBRARY_PATH

После этого программа rezultdyn будет прекрасно работать. В случае, если у Вас в системе эта переменная среды уже уставновлена, то, чтобы не испортить ее значение, надо новый каталог прибавить к старому значению. Делается это другой командой:

dron:~# LD_LIBRARY_PATH=/root:$ dron:~# export LD_LIBRARY_PATH

Если Вы обнулите эту переменную, то снова библиотека перестанет работать:

dron:~# LD_LIBRARY_PATH="" dron:~# export LD_LIBRARY_PATH dron:~# ./rezultdyn ./rezultdyn: error in loading shared libraries: libfsdyn.so: cannot open shared object file: No such file or directory dron:~#

Вы также параллельно можете зайти в систему под другим пользователем или даже тем же самым, но если Вы захотите просмотреть значение LD_LIBRARY_PATH, то увидите ее прежнее значение. Это означает, что два разных пользователя Linux не могут влиять на работу друг друга, а это и есть самое главное хорошее отличие систем Unix от большинства других систем.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *