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

8

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

export PATH=$HOME/local/bin:$PATH
export LD_LIBRARY_PATH=$HOME/local/lib:$LD_LIBRARY_PATH
export TESTER="MY TEST VAR"

$@

Когда я использую это для вызова, bashнапример, это работает:

kjfletch@flatbed:~$ envrun.sh bash
kjfletch@flatbed:~$ echo $LD_LIBRARY_PATH
/home/kjfletch/local/lib:
kjfletch@flatbed:~$ echo $TESTER
MY TEST VAR

Когда я использую его для вызова терминала ( xterm, aterm, ...) моя LD_LIBRARY_PATHполучает снята с охраны:

kjfletch@flatbed:~$ echo $LD_LIBRARY_PATH

kjfletch@flatbed:~$ echo $TESTER

MY TEST VAR

Почему это происходит? Как я могу это остановить? (Я использую Debian 5.0)

Обновить

Мой терминал не вызывает bash в качестве логина:

kjfletch@flatbed:~$ echo $0
bash

My LD_LIBRARY_PATHне отображается ни в одном из файлов запуска bash (кроме .bash_history и ~ / .profile не существует.):

kjfletch@flatbed:~$ grep "LD" ~/.bash*
kjfletch@flatbed:~$ grep "LD" /etc/bash.bashrc 
kjfletch@flatbed:~$ grep "LD" /etc/profile 
kjfletch
источник
Являются ли какие-либо из этих файлов запуска вызывающей командой «source» или «.» Команда, чтобы ввести другие сценарии запуска? Если это так, один из них может быть виновником.
Кевин Панко
Не отвечает на ваш вопрос, но действительно хорошо бы избавиться от необходимости в LD_LIBRARY_PATH (причины: 1 2 3 ). Вы можете, например, отредактировать /etc/ld.so.conf или скомпилировать любые пользовательские библиотеки, которые есть в ~ / local, таким образом, чтобы они знали, где найти свои библиотеки (см. Ссылки, которые я дал).
DevSolar

Ответы:

9

Конечный двоичный файл наиболее вероятно setgidсгруппирован utmp. Setuid и setgid бинарные файлы не установлены LD_LIBRARY_PATHпо соображениям безопасности; увидеть ld.so(8):

Необходимые разделяемые библиотеки, необходимые программе, ищутся в следующем порядке

  • Использование переменной окружения LD_LIBRARY_PATH( LD_AOUT_LIBRARY_PATHдля программ a.out). За исключением случаев, когда исполняемый файл является двоичным файлом setuid / setgid, в этом случае он игнорируется.
Тедди
источник
4

В терминале (xterm, aterm и т. Д.) Проверьте, как была вызвана оболочка: оболочка входа в систему покажет «-bash», а не входящая в систему оболочка - «bash» при вызове echo $0.

$ echo $0
-bash
$ bash
$ echo $0
bash

Оболочка входа в систему bash будет читать следующее по порядку:

  1. / И т.д. / профиль
  2. ~ / .Bash_profile
  3. ~ / .Bash_login
  4. ~ / .Profile

Проверьте, существует ли какой-либо из этих файлов и сбрасывают ли они переменную. Вы также должны следить за любыми файлами, которые эти файлы включают.

Если bash не вызывается как оболочка входа в систему, он все равно будет читать приведенные ниже файлы, если определено, что это интерактивная оболочка.

  1. /etc/bash.bashrc
  2. ~ / .Bashrc

Простой способ определить тип вызываемой оболочки bash - определить ваши .bash_profile и .bashrc, а также echo "Login shell" и "Interactive shell" соответственно.

Как только вы узнаете, какая оболочка вызывается, у вас есть возможность добавить скрипт в файл .bashrc или .bash_profile в вашем домашнем каталоге. Кроме того, вы можете отключить сброс LD_LIBRARY_PATH.

Обратите внимание, что если ваш .bashrc или .bash_profile защищен защитником, подобным приведенному ниже, вам, возможно, придется вызвать свой сценарий вне его:

if [ "X$BASH_SOURCED" != "XYES" ]; then
        export BASH_SOURCED=YES

fi

Такие охранники, как правило, размещаются для предотвращения многократного получения сценария за сеанс.

Редактировать: Если проверено, что утомительно, чтобы отследить, где переменная сбрасывается, и у вас есть доступ к / etc / profile или /etc/bash.bashrc, например, вы можете временно добавить «set -x» в верхней части скрипт, чтобы увидеть все команды, которые выполняются. Вывод будет довольно многословным, поэтому сначала выполните «set -x» в вашей оболочке и выполните несколько команд, чтобы вы знали, чего ожидать.


источник
+1 Спасибо за информацию. Я обновил свой ОП в ответ на ваш ответ.
kjfletch
Видите ли вы такое же поведение, если вы вводите новую оболочку bash на том же терминале, набирая bash? Кстати, вам также нужно проверить файлы, которые вызываются из /etc/bash.bashrc и / etc / profile - один из них может сбрасывать переменную. В качестве альтернативы, используйте set -xопцию отладки, чтобы получить дамп всего, что делается с момента создания оболочки.
set -xСвалка не имеет никакого отношения к LD_LIBRARY_PATH. Призрак сброшен.
kjfletch
4

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

Проверьте руководство по bash для более подробной информации. Я подозреваю, что / etc / profile или ~ / .bash_profile что-то делает для сброса переменной LD_LIBRARY_PATH.


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

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

strace -v -f -e trace=process -o strace_output.txt envrun.sh xterm

Теперь файл strace_output.txt будет показывать каждый системный вызов, выполненный вашим сценарием и каждым дочерним процессом, и вы сможете увидеть, какой из процессов был последним с LD_LIBRARY_PATH, прежде чем он был удален.

Кевин Панко
источник
2

(Этот вопрос очень старый, но я только что столкнулся с той же проблемой, и я документирую решение для последующих :)

У меня была эта проблема с экраном GNU (мультиплексор терминала), но это может случиться и с обычным терминалом. Тедди был прав в моем случае, экран имеет setguid.

$ ls -l /usr/bin/screen
-rwxr-sr-x 1 root 84 361016 Mar 30  2011 /usr/bin/screen
      ^

Моим решением было сохранить LD_LIBRARY_PATH перед выполнением, а затем восстановить его. Поэтому я создал оболочку ~ / bin / screen (поместите ~ / bin в PATH) со следующим содержимым:

#!/bin/bash

# somehow, screen resets LD_LIBRARY_PATH.
# save it here, and restore it in .bashrc
export PRESERVE_LD_LIBRARY_PATH="$LD_LIBRARY_PATH"
/usr/bin/screen "$@"

а затем сделал его исполняемым с chmod +x ~/bin/screen. Возможно, вам придется открыть новую оболочку, чтобы она могла забрать обертку.

Затем я добавил следующее в ~ / .bashrc. Помните, что ~ / .bashrc получает источник каждый раз, когда вы запускаете bash, в отличие от ~ / .bash_profile, который получает только при входе в систему (обычно при запуске или при входе через ssh).

if [[ "$PRESERVE_LD_LIBRARY_PATH" != "" ]]; then
    export LD_LIBRARY_PATH="$PRESERVE_LD_LIBRARY_PATH"
    #echo "restored LD_LIBRARY_PATH"
    export -n PRESERVE_LD_LIBRARY_PATH
fi

Теперь screen (или aterm, xterm, ... просто замените его выше) должен сохранить $ LD_LIBRARY_PATH как хотелось бы.

JDM
источник
Вы также можете восстановить LD_LIBRARY_PATHв .screenrc(вместо .bashrc): setenv LD_LIBRARY_PATH "$PRESERVE_LD_LIBRARY_PATH"затемunsetenv PRESERVE_LD_LIBRARY_PATH
nandhp
0

Кажется, что у вас есть некоторый файл .bashrc (или эквивалентный) в вашем домашнем каталоге, который определяет эту переменную. Я не знаю намного больше деталей, хотя.

Edit Хорошо, так как запуск bash работает, я думаю, не .bashrc. Но может быть какой-то другой файл конфигурации, который выполняется таким же образом, когда вы запускаете xterm или aterm.

Gnoupi
источник
Это была моя оригинальная мысль. После долгих поисков ничего не найдено. У меня есть преимущество, что у меня очень чистый (NEW) $ HOME.
kjfletch
0

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

Итак, поместите его в ваш .bash_profile или .bashrc, если вы хотите, чтобы он появился в новом окне.

Другая альтернатива - передать xterm (например) аргумент для запуска сценария запуска. Не выходите в конце этого сценария ....

kmarsh
источник
Мне придется прибегнуть к этому, я думаю. Я, вероятно, получу исходные переменные окружения как в .xinitrc, чтобы они были у моего оконного менеджера, так и в .bashrc, чтобы они были у моих окон терминала.
kjfletch