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

Мой 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 

6 ответов6

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» в вашей оболочке и выполните несколько команд, чтобы вы знали, чего ожидать.

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 как хотелось бы.

0

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

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

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

0

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

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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .