使用 ld-linux.so 调用脚本?

使用 ld-linux.so 调用脚本?

我刚刚下载了一个tar文件,该文件应该包含运行我们可以调用的程序所需的所有内容some_binary。我提取了它的内容,我看到以下内容:

  • 一个二进制文件(我们称之为some_binary
  • 包含各种动态库(.so 文件)的文件夹lib,例如/lib/ld-linux-x86-64.so
  • 和一个名为的 shell 脚本some_binary.sh

该脚本有以下内容:

#!/bin/bash
`dirname "$0"`/lib/ld-linux-x86-64.so.2   `dirname "$0"`/some_binary "$@"

并运行它似乎./some_binary.sh some arguments运行./some_binary正确。奇怪的是,运行以下脚本:

#!/bin/bash
LD_LIBRARY_PATH=$CWD/LIB:$LD_LIBRARY_PATH
./some_binary "$@"

因为./my_script.sh some arguments不起作用。它会导致重定位错误(未定义的符号),可能是由于错误地加载了下面的库./lib

此外,从命令行运行以下两个语句会导致segmentation fault

> LD_LIBRARY_PATH=$CWD/LIB:$LD_LIBRARY_PATH
> ./some_binary some arguments

对此,我的问题是:

  1. 第一个脚本的作用是什么?
  2. 为什么我在这三种尝试中得到不同的结果?为什么我不能直接添加$pwd/lib然后LD_LIBRARY_PATH运行some_binary

答案1

该程序带有自己的动态加载器。程序很少需要自己的动态加载器:通常您系统上的动态加载器也可以工作。如果程序链接到 GNU libc 之外的标准库,或者链接到使用奇怪设置编译的 GNU libc,则这可能是必要的。

告诉加载程序在哪里可以找到程序的首选库就足够了。你的尝试几乎做到了这一点,但不完全是。如果LD_LIBRARY_PATH环境中尚不存在,则赋值LD_LIBRARY_PATH=$CWD/LIB:$LD_LIBRARY_PATH仅定义了 shell 变量,而不是环境变量,因此程序看不到任何东西。此外,$CWD通常会扩展为空字符串,您可能指的是$PWD或更好$(dirname "$0")(即包含脚本的目录)。另请注意,您在问题中使用了lib和不一致的内容。LIB尝试

#!/bin/sh
export LD_LIBRARY_PATH="$(dirname "$0")/lib:$LD_LIBRARY_PATH"
exec "$(dirname "$0")/some_binary" "$@"

或者更好的是,如果之前没有定义,则避免在末尾有一个空条目LD_LIBRARY_PATH(这可能很糟糕,因为空条目代表当前目录,尽管在路径末尾,只有在库不存在时才有害)没有找到它应该在的地方):

#!/bin/sh
export LD_LIBRARY_PATH="$(dirname "$0")/lib:$LD_LIBRARY_PATH"
case "$LD_LIBRARY_PATH" in *:) LD_LIBRARY_PATH=${LD_LIBRARY_PATH%:};; esac
exec "$(dirname "$0")/some_binary" "$@"

相关内容