前言

近日在添加一个镜像内依赖时,出现了令人非常困惑的现象:

明明依赖文件(an excutable binary)是存在的,但执行却无法找到文件;这篇文章就来记录一下这个问题的解决过程

需要了解的词

  • 32-bit & 64-bit
    一般指CPU能处理的最大位数,64位的软件不能在32位的机器上运行,而64位的系统一般这两种类型的都支持

解决过程

确认系统位数及依赖binary的位数

使用uname -a查看系统位数

image-20221023231747496

可以看到x86_64,64位系统

再查看依赖binary的位数,使用file命令(file命令会输出一个二进制文件的详细信息)

企业微信截图_76387d77-7bb9-488f-a517-0ae82b65057e

可以看到也是x86-64,64位的excutable binary

到这里可以排除位数不兼容的问题,并且只要安装了ia32-libs依赖或是更细粒度的libc6-i386(GNU C Library: 32-bit shared libraries for AMD64),就可以在64位系统(Ubuntu)上运行32位软件了

确认是否缺少依赖

使用ldd <file-name>命令可以检查是否有任何not found的依赖库

在本机上可以看到所需动态库都是全的,运行没有问题

企业微信截图_e7838d8b-da54-4661-b9f1-535427ba2a9f

再到镜像中使用ldd查看依赖情况:

企业微信截图_aa62be05-c9bb-4614-a806-d4cebd3d911c

可以看到是少了一些动态库依赖的,所以接下来我们尝试补全这些依赖

image-20221023233532440

image-20221023233512944

image-20221023233459188

由于我们的镜像是基于 Alpine 3.15的,所以这里我们使用apk add把上面的依赖通通装上

验证

最后再执行验证:

企业微信截图_bb82970a-c72c-40bc-a535-3784cf74233f

我们的系统终于能正常运行这个依赖文件了🥳

总结

No such file or directory问题可以按以下步骤排查:

  1. 文件路径是否真的不存在

  2. 文件存在但它是一个无效的符号链接

  3. 文件确实存在,但架构 / 位数不匹配(可使用file 命令确认)

  4. 文件存在且架构适配,那么问题就可能出现在文件加载程序上:

    1. 使用file命令查看:

      1
      2
      file lmgrd
      lmgrd: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-lsb-x86-64.so.3, for GNU/Linux 2.6.18, stripped

      比如这里可以看到解释器/lib64/ld-lsb-x86-64.so.3,如果它不存在我们是无法运行该程序的,对这个例子来说解决方案就将是sudo apt-get install lsb

    2. script’s loader 问题 (详见 this answer)

    3. 缺失动态库依赖——使用ldd命令查看是否有缺失动态库依赖,并补全依赖