ldd 等效项在找不到库时失败

ldd 等效项在找不到库时失败

假设我ldd /bin/ls在删除 pthread 库的情况下执行操作。我得到

linux-vdso.so.1 (0x00007ffcc3563000)

libselinux.so.1 => /lib64/libselinux.so.1 (0x00007f87e5459000)
libcap.so.2 => /lib64/libcap.so.2 (0x00007f87e5254000)
libc.so.6 => /lib64/libc.so.6 (0x00007f87e4e92000)
libpcre.so.1 => /lib64/libpcre.so.1 (0x00007f87e4c22000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f87e4a1e000)
/lib64/ld-linux-x86-64.so.2 (0x00005574bf12e000)
libattr.so.1 => /lib64/libattr.so.1 (0x00007f87e4817000)
libpthread.so.0 => not found

返回码为零。在这种情况下是否有命令返回错误?类似的东西

#!/bin/bash
if [[ ! -z $(ldd ${target} | grep 'not found') ]]; then
   exit 1
fi

答案1

ldd在 Linux 上要小心;它只是一个bash脚本,至少在较旧的系统上,将LD_TRACE_LOADED_OBJECTS=1在其环境中运行给定的程序。

这意味着,如果程序有除 之外的其他解释器/lib{64,32}/ld-*,则该程序将以您的目标作为其第一个参数运行,即使您无意这样做。如果您ldd在其他用户拥有的可执行文件上运行,则该用户将拥有反而。

您可以使用 .检查 ELF 标头中定义的解释器readelf -l "$target" | grep interpreter

在较新的系统上,ldd已更改为将目标作为参数传递给从“好”解释器列表中获取的解释器(例如/lib64/ld-linux.so.2 target);我觉得这并不令人信服,但如果足够安全,就由你来决定。

如果您发现所有这些都可以接受,最简单的方法是:

if ldd "$target" | grep -q 'not found'; then
   echo >&2 "$target is missing dependencies"
   exit 1
fi

如果在“跟踪模式”下调用(如来自 ldd),Linux 上的默认动态加载程序将始终以 0 状态退出,并且无法通过命令行开关或环境变量更改它;你必须更改它的源代码。

相关内容