ldd是首选因其直观显示依赖库名及实际路径,能快速识别“not found”问题,但会通过调用动态链接器模拟加载,可能触发恶意二进制的初始化代码,故对不可信文件应改用readelf -d或objdump -p等不执行的安全替代方案。

直接用 ldd 查最准,但必须确保目标文件有执行权限,且不能对不可信二进制盲目使用。
为什么 ldd 是首选,但它会“执行”程序?
ldd 本质是调用动态链接器(如 /lib64/ld-linux-x86-64.so.2)模拟加载过程,从而列出所有 NEEDED 的共享库及其实际路径。它输出直观、带路径、能一眼看出 not found 问题。
但这也带来风险:如果目标文件是恶意构造的,ldd 可能触发其初始化代码(比如某些带构造函数的 C++ 程序)。所以:
- 对系统自带命令(如
/bin/ls、/usr/bin/python3)放心用 - 对来源不明、自行编译未审计的二进制,优先改用
readelf或objdump - 若提示
not a dynamic executable,说明该文件是静态链接或脚本(如 shell 脚本),ldd不适用
readelf -d 和 objdump -p 怎么用才不漏信息?
这两个命令只解析 ELF 文件头和动态段,完全不执行目标文件,更安全,但只输出库名,不显示路径。
典型操作链:
-
readelf -d /path/to/cmd | grep NEEDED→ 得到依赖库名列表,例如libssl.so.1.1 -
ldconfig -p | grep 'libssl\.so\.1\.1$'→ 在系统缓存中找匹配的完整路径 - 若没结果,再查环境变量:
echo $LD_LIBRARY_PATH,或手动find /usr/local/lib /opt -name 'libssl.so.1.1' 2>/dev/null
注意:objdump -p 输出更简洁,但某些精简版系统可能没装 binutils;readelf 属于 elfutils,多数发行版默认自带。
遇到 not found 却找不到对应库,下一步查什么?
当 ldd 显示类似 libopencv_core.so.405 => not found,别急着下载,先确认三件事:
- 该库是否真缺失?运行
ldconfig -p | grep opencv_core,看有没有其他版本(如libopencv_core.so.406)——版本号不匹配也会报not found - 路径是否在搜索范围内?检查
/etc/ld.so.conf.d/下是否有对应目录,或$LD_LIBRARY_PATH是否包含安装路径 - 权限是否被阻断?
ls -l /path/to/libopencv_core.so.405确认文件可读,且所在目录有执行(x)权限(否则动态链接器无法进入目录)
常见陷阱:把库文件拷到 /usr/local/lib 后忘了运行 sudo ldconfig 刷新缓存,导致 ldd 仍查不到。
脚本类命令(如 python 包装的 CLI)怎么查真正依赖?
像 pip install 安装的命令(如 jq 的 Python 版、poetry),本身是 Python 脚本,ldd 查的是 Python 解释器的依赖,不是业务逻辑依赖的 .so。
此时应分两层看:
- 先查解释器:
ldd $(which python3)—— 确保 Python 自身依赖正常 - 再查扩展模块:若用到
numpy、torch等含 C 扩展的包,它们的.so文件藏在site-packages里,可用python3 -c "import numpy; print(numpy.__file__)"定位,然后对其中的.so文件(如_multiarray_umath.cpython-*.so)单独跑ldd
混淆点在于:Python 脚本本身不“链接”这些库,但导入时由解释器动态加载 —— 所以出错时,错误来自 import 阶段,而非启动脚本阶段。


















