为什么我的LD_LIBRARY_PATH无法设置启动终端?


8

我有一个shell脚本来设置一些环境变量并启动作为参数发送的任何程序:

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

当我使用它来调用终端(xtermaterm,...)我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 

那些启动文件中是否有任何调用“源”命令或“。”的文件?命令引入其他启动脚本?如果是这样,可能是罪魁祸首之一。
凯文·潘科

不能回答您的问题,但是真正的好处是摆脱对LD_LIBRARY_PATH 的需要(原因:1 2 3)。例如,您可以编辑/etc/ld.so.conf,或以〜/ local编译用户定义的任何lib的方式,使他们知道在哪里可以找到其库(请参阅我提供的链接)。
DevSolar

Answers:


9

终端二进制文件最有可能setgid分组utmpLD_LIBRARY_PATH出于安全原因未设置Setuid和setgid二进制文件;见ld.so(8)

程序所需的必要共享库按以下顺序搜索

  • 使用环境变量LD_LIBRARY_PATHLD_AOUT_LIBRARY_PATH用于a.out程序)。除非可执行文件是setuid / setgid二进制文件,否则将被忽略。

4

在终端(xterm,aterm等)中,检查外壳程序的调用方式:调用时,登录外壳程序将显示“ -bash”,非登录外壳程序将显示“ bash” echo $0

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

登录bash shell将按顺序读取以下内容:

  1. / etc / profile
  2. 〜/ .bash_profile
  3. 〜/ .bash_login
  4. 〜/ .profile

检查这些文件是否存在,以及它们是否重置了变量。您还必须遵循这些文件包含的所有文件。

如果未将bash用作登录外壳,则在确定为交互式外壳的情况下,它仍将读取以下文件。

  1. /etc/bash.bashrc
  2. 〜/ .bashrc

确定bash shell调用类型的一种简单方法是定义.bash_profile和.bashrc,然后分别回显“ Login shell”和“ Interactive shell”。

一旦知道了要调用的外壳类型,就可以选择将脚本添加到主目录中的.bashrc或.bash_profile文件中。或者,您可以禁用LD_LIBRARY_PATH的重置。

请注意,如果您的.bashrc或.bash_profile受类似于以下内容的防护措施保护,则可能必须在其外部调用脚本:

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

fi

通常放置此类防护措施以防止脚本在会话中多次获得。

编辑:如果证明tedius可以跟踪到要重置变量的位置,并且您可以访问/ etc / profile或/etc/bash.bashrc,例如,可以在“ / etc / profile”顶部附近临时添加“ set -x”脚本以查看所有执行的命令。输出将非常冗长,因此首先在您的shell中执行“ set -x”并运行一些命令,以使您知道会发生什么。


+1感谢您的信息。我已根据您的回答更新了我的OP。
kjfletch

如果在同一终端上通过输入bash输入新的bash shell,是否会看到相同的行为?顺便说一句,您还需要检查从/etc/bash.bashrc和/ etc / profile中调用的文件-其中之一可能会取消设置变量。或者,使用set -xdebug选项获取自创建Shell以来完成的所有操作的转储。

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屏幕(终端多路复用器)上遇到了这个问题,但在常规终端上也可能会发生。泰迪(Teddy)对我来说是对的,屏幕已设置好。

$ 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

现在,屏幕(或aterm,xterm,...只是在上面替换它)应该保留所需的$ LD_LIBRARY_PATH。


您也可以恢复LD_LIBRARY_PATH.screenrc(代替.bashrcsetenv LD_LIBRARY_PATH "$PRESERVE_LD_LIBRARY_PATH",然后unsetenv PRESERVE_LD_LIBRARY_PATH
nandhp

0

看来您的主目录中有一些.bashrc(或等效文件)文件定义了此变量。我不知道更多细节。

编辑好吧,因为启动bash可以,所以我猜不是 .bashrc。但是也许其他一些配置文件在启动xterm或aterm时恰好以相同的方式执行。


这是我最初的想法。经过大量搜索后,找不到任何东西。我有一个非常干净的(新)$ HOME的好处。
kjfletch

0

大多数窗口系统在启动终端窗口时都会重新创建登录过程,这主要是因为终端窗口成为窗口管理器的子级,而不是启动外壳程序的子级。

因此,如果希望它显示在新窗口中,请将其放在.bash_profile或.bashrc中。

另一种选择是使用xterm(例如)传递参数来运行启动脚本。不要在该脚本的结尾退出。


我认为我将不得不诉诸于此。我可能会在.xinitrc中同时提供环境变量,以便我的窗口管理器也可以在.bashrc中提供它们,以便我的终端窗口也可以使用它们。
kjfletch
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.