Contents

执行二进制文件时“没有此类文件或目录”错误

1. 概述

在本教程中,我们将追踪当我们尝试执行程序的二进制文件时可能导致“没有这样的文件或目录”错误的原因。我们将使用在大多数 Linux 发行版上可用的objdumplddreadelf 命令。

2. 问题介绍

当我们尝试执行从 Internet 下载的程序的二进制文件时,或者当我们将自己的程序部署到新环境时,我们可能会收到“没有这样的文件或目录”错误,这可能是由于缺少库或程序解释器。

2.1. 缺少库

假设我们要运行某个二进制文件:

$ ./binaryfile
./binaryfile: error while loading shared libraries: libbooster.so.0: cannot open shared object file: No such file or directory

错误消息说它找不到共享库libbooster.so.0

我们可以构建或下载缺少的库,并将其放在二进制文件可以找到它的目录中,例如,在二进制文件所在的同一目录中或 PATH 变量 中的目录之一。之后,我们可以尝试再次运行二进制文件:

$ ./binaryfile
./binaryfile: error while loading shared libraries: libssl.so.1.0.0: cannot open shared object file: No such file or directory

它说找不到另一个图书馆。我们可以不断重复这个过程,直到找到所有库,或者我们可以使用 Linux 命令,例如objdumplddreadelf来列出二进制文件需要的所有库。

2.2. 缺少程序解释器

在另一种情况下,我们可能会得到另一个类似的错误但没有给出有意义的消息:

$ ./binaryfile
-bash: ./binaryfile: No such file or directory

对于这种错误,假设binaryfile文件存在并且具有正确的权限,通常是因为我们的系统没有运行二进制文件的程序解释器。我们可以使用 Linux 实用程序(例如*readelf)*来跟踪可能导致错误的原因。

3. 使用objdump命令

让我们使用objdump 命令列出二进制文件需要的所有库:

$ objdump -p binaryfile | grep NEEDED
    NEEDED libbooster.so.0
    NEEDED libcrypto.so.1.0.0
    NEEDED libpthread.so.0
    ...
    NEEDED libgcc_s.so.1
    NEEDED libc.so.6

我们可以遍历二进制文件需要的所有库,并确保我们的系统拥有所有这些库。

4.使用ldd命令

另一种检查我们的系统是否具有二进制文件所需的所有库的方法是使用ldd命令

$ ldd binaryfile
    libbooster.so.0 => not found
    libcrypto.so.1.0.0 => not found
    libboost_thread.so.1.68.0 => not found
    ...
    libhogweed.so.4 => /lib/x86_64-linux-gnu/libhogweed.so.4 (0x00007fb0f5036000)
    libgmp.so.10 => /lib/x86_64-linux-gnu/libgmp.so.10 (0x00007fb0f4fb3000)
    libffi.so.6 => /lib/x86_64-linux-gnu/libffi.so.6 (0x00007fb0f4fa9000)

ldd命令提供了有关二进制文件所需库的更多详细信息。 请注意,我们不应该在不受信任的变量上使用ldd,因为它可能会通过尝试直接执行程序来尝试获取依赖项信息

5. 使用readelf命令

另一个命令不仅会提供有关二进制文件所需的库的信息,还会提供“没有这样的文件或目录”错误的另一个常见原因的信息是readelf

让我们列出二进制文件需要的所有库:

$ readelf -a binaryfile | grep NEEDED
0x0000000000000001 (NEEDED) Shared library: [libbooster.so.0]
0x0000000000000001 (NEEDED) Shared library: [libcrypto.so.1.0.0]
0x0000000000000001 (NEEDED) Shared library: [libboost_thread.so.1.68.0]
...
0x0000000000000001 (NEEDED) Shared library: [libgcc_s.so.1]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]

验证程序解释器是否存在于我们的系统中

$ readelf -a binaryfile | grep interpreter
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]

该命令提供的信息表明它正在请求名为ld-linux-x86-64.so.2的程序解释器。

ld-linux-x86-64.so.2是一个动态链接器程序,用于在 64 位系统上运行 32 位程序。

如果程序解释器不存在,我们通常可以从官方包存储库下载它。具有此文件的 Debian 或 Ubuntu 软件包是libc6-i386