【问题标题】:bash claims executable file does not exist when trying to execute it, but it does existbash 在尝试执行时声称可执行文件不存在,但它确实存在
【发布时间】:2019-06-25 13:08:53
【问题描述】:

我无法解释的最奇怪的经历让我把头发拔了出来。我有一个二进制可执行文件 MMM 并且它存在,我可以看到它具有 x 权限集,当我按下 TAB 键并且文件确认其可执行文件时,bash 甚至会自动完成名称,但是会发生这种情况:

~/tmp$ ls -l
total 56
-rwxrwxr-x 1 polyphemus polyphemus 56948 Jun 25 22:43 MMM
~/tmp$ file MMM
MMM: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-, for GNU/Linux 2.2.5, stripped
~/tmp$ ./MMM
-bash: ./MMM: No such file or directory

所以我从另一台服务器复制了这个文件,并确保我没有发生一些奇怪的文件损坏,而不是解释 bash 的荒谬声称文件不存在,我将文件复制到 NAS 并从 NAS 回到另一台服务器并重复完全相同的实验,只是发生了这种情况:

~/tmp$ ls -l
total 56
-rwxr-xr-x 1 bernd bernd 56948 Jun 25 22:53 MMM
~/tmp$ file MMM 
MMM: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-, for GNU/Linux 2.2.5, stripped
~/tmp$ ./MMM
JAVA_HOME is not set. ./MMM cannot start.

如果有帮助的话,它们都是 Linux Mint 盒子,它可以工作的是一台装有 Mint 19 的开发机器,而不能工作的是一台全新安装的 Mint 19.1。

安装工作正常,其他可执行文件运行正常,然后我可以使用 ./file 在 bash 中运行。

我研究并比较了商店,一无所获,别名也一无所获。这让我把头发拉出来。我希望有人以前看过这个。

【问题讨论】:

  • interpreter /lib/ld- 对我来说看起来不对,你自己编译(链接)了吗?
  • 不,这是我使用多年的旧 32 位 Java 程序。它运行正常,在上面的开发盒上运行,也在这个重新安装的盒子上运行。对于非常好奇的关于它的窗口:“MusicIP Mixer 1.8(构建日期:2007 年 7 月 21 日)” - 我承认这是 bash 的消息让我感到困惑。
  • 您的系统不支持 i386 32 位架构。您需要将 32 位支持库安装到 Linux Mint 系统。请参阅:blog.linuxmint.com/?p=2211
  • 聪明的想法!我在这里检查:blog.linuxmint.com/?p=2211 并运行了两个声明的命令,但行为没有改变。不过还没有重启。

标签: bash


【解决方案1】:

感谢丹尼斯威廉姆森提供的指针,问题可以描述如下:

  1. 这是一个众所周知的问题。因为存在内核限制,这意味着当内核尝试加载运行二进制文件所需的文件时,bash 仅接收状态代码(用于“找不到文件”的状态代码)而没有任何描述性数据。该消息确实具有令人沮丧的误导性,这是一个广为人知和理解的问题。
  2. 正如问题本身所指出的,这是一个 ELF 二进制文件:https://en.wikipedia.org/wiki/Executable_and_Linkable_Format,并且这种二进制文件所需的解释器可以用产生[Requesting program interpreter: /lib/ld-linux.so.2] 的readelf -a MMM | grep interpreter 进行预测
  3. 很容易看到我的系统上缺少此文件,事实证明,要安装它,我们只需使用 sudo apt install libc6:i386 安装用于 32 位架构的 lib6 库

在这样做之后,让我感到困惑的问题场景现在看起来像工作场景:

~/tmp$ ls -l
total 56
-rwxrwxr-x 1 polyphemus polyphemus 56948 Jun 25 22:43 MMM
~/tmp$ file MMM
MMM: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-, for GNU/Linux 2.2.5, stripped
~/tmp$ ./MMM
JAVA_HOME is not set. ./MMM cannot start.

二进制文件运行得很好!

一个令人愉快的结果。非常感谢 StackOverflow 和 Dennis Williamson。

【讨论】:

    【解决方案2】:

    它可能是一个无法加载的库(因为它在您的系统上不存在),并带有错误消息。试试:

    ldd .MMM

    这将为您提供尝试加载的动态库,并告诉您是否缺少一个。

    【讨论】:

    • $ ldd ./MMM 不是动态可执行文件
    【解决方案3】:

    这个错误似乎与 JAVA_HOME 环境变量有关

    JAVA_HOME is not set. ./MMM cannot start.
    

    只需从您使用的任何 java 版本设置 JAVA_HOME

    你可以像这样内联运行它

    JAVA_HOME=$(readlink -f /usr/bin/javac | sed "s:/bin/javac::") ./MMM
    

    【讨论】:

    • 你误会了。该消息由正常工作的系统发出。事实上,这个可执行文件通常是从一个设置 JAVA 环境变量的 bash 脚本启动的,然后运行这个可执行文件。但是脚本说当它试图运行它时可执行文件不存在。也就是说,我没有共享脚本层,这会分散注意力。问题是报告您处理的消息的第二种情况工作正常,这是 bash 报告文件甚至不存在的顶级情况!二进制文件必须运行才能尝试加载 JRE 并失败...
    猜你喜欢
    • 2021-08-12
    • 2022-06-10
    • 2011-03-18
    • 2019-01-07
    • 1970-01-01
    • 2013-12-11
    • 1970-01-01
    • 1970-01-01
    • 2018-09-06
    相关资源
    最近更新 更多