我有一个 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
当我用它来调用终端(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
答案1
终端二进制文件最有可能setgid
分组。出于安全原因,utmp
setuid 和 setgid 二进制文件未设置;请参阅:LD_LIBRARY_PATH
ld.so(8)
按以下顺序搜索程序所需的必要共享库
- 使用环境变量
LD_LIBRARY_PATH
(LD_AOUT_LIBRARY_PATH
用于 a.out 程序)。除非可执行文件是 setuid/setgid 二进制文件,在这种情况下它将被忽略。
答案2
在终端 (xterm、aterm 等) 中,检查 shell 是如何调用的:当您调用时,登录 shell 将显示“-bash”,非登录 shell 将显示“bash” echo $0
。
$ echo $0
-bash
$ bash
$ echo $0
bash
登录 bash shell 将按顺序读取以下内容:
- /etc/配置文件
- 的〜/ .bash_profile
- 〜/ .bash_login
- 〜/ .profile
检查这些文件是否存在,以及它们是否重置了变量。您还必须跟踪这些文件包含的任何文件。
如果 bash 未作为登录 shell 调用,则如果确定为交互式 shell,它仍将读取以下文件。
- /etc/bash.bashrc
- ~/.bashrc
确定调用的 bash shell 类型的简单方法是定义 .bash_profile 和 .bashrc,并分别回显“登录 shell”和“交互式 shell”。
一旦知道要调用的 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”以查看所有执行的命令。输出将非常详细,因此请先在 shell 中执行“set -x”并运行一些命令,这样您就知道会发生什么。
答案3
bash 将根据其启动方式使用不同的启动脚本。有七种不同的启动方式,但最重要的是登录 shell 与非登录交互式 shell。
查看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_输出.txt将显示脚本和每个子进程进行的每个系统调用,并且您将能够看到哪个进程在被删除之前是最后一个拥有 LD_LIBRARY_PATH 的进程。
答案4
看起来你的主目录中有一些 .bashrc(或等效文件)定义了这个变量。不过我不知道更多细节。
编辑好的,因为启动 bash 可以工作,所以我猜不是.bashrc。但是当您启动 xterm 或 aterm 时,也许会以相同的方式执行其他一些配置文件。