为什么LD_PRELOAD对没有shebang的脚本生效?

时间:2016-10-11 16:58:51

标签: linux bash elf ld-preload

如果,当我运行脚本时,我使用LD_PRELOAD指定要预加载的库,我发现只有当脚本有一个shebang行时才会预加载库。例如,给定此脚本:

# Not a shebang
echo Hello

和这个命令:

LD_PRELOAD=/path/to/preload_me.so ./script.sh

脚本在没有加载库的情况下运行,我可以通过其初始化代码的(非)效果进行监视。

另一方面,如果我添加一个shebang行:

#!/bin/sh
echo Hello

...当我通过相同的命令运行脚本时,库加载。对于确切指定哪个解释器似乎并不重要;当然我也可以使用/bin/bash或任何其他sh - 我试过的家庭shell。

为什么会有区别,有没有办法确保在给定的shell简单命令之前预先加载给定的库,而不管命令是什么?

(改编自another question,其作者拒绝按照这些条款提出的问题。)

1 个答案:

答案 0 :(得分:7)

(根据我对引用的其他问题的回答改编。​​)

必须了解LD_PRELOAD变量对操作系统或shell没有特殊意义。它有意义和影响 - 如果它有它们 - 只与动态链接器一起使用。如果未使用动态链接器,则LD_PRELOAD只是环境中的另一个变量。同样,如果动态链接器无法识别该变量(例如,在OS X上)。

还必须了解,当执行名称对应于不是可执行格式但包含shebang行的文件的命令时,即使它是shell本身,也会执行指定的解释器。如果解释器是ELF二进制文件,那么它将使用动态链接器。另一方面,如果没有shebang行,则bash在子shell环境中执行文件的内容,这不需要使用动态链接器;相反,shell只是分叉。其他shell可能会也可能不会这样做。

识别ELF以外的可执行格式也很重要。你不太可能在现代的基于ELF的系统上遇到这样的二进制文件,但你不应该排除这种可能性。

底线:无法确保在通过bash或用户选择的其他shell执行的任意shell命令的进程空间中预加载给定的动态库。如果您需要为任何或每个任意命令预加载这样的库,那么您需要更严格地控​​制执行环境,可能是通过提供自定义shell,也可能是自定义动态链接器,并防止使用任何其他命令。 / p>