已存在的文件出现 ENOENT。为什么?

已存在的文件出现 ENOENT。为什么?
uprego@udv1320ku12:~$ ls /usr/bin/ -thral | grep java
-rwxr-xr-x 1 root root 78 Aug 25 2010 javacc
-rwxr-xr-x 1 root root 2.5K Mar 13 2012 dh_nativejava
lrwxrwxrwx 1 root root 22 Sep 23 19:40 java -> /etc/alternatives/java
...

/usr/bin/java存在,至少作为对可能存在且可执行的事物的引用。

uprego@udv1320ku12:~$ strace /usr/bin/java
execve("/usr/bin/java", ["/usr/bin/java"], [/* 45 vars */]) = 0
...

似乎 /usr/bin/java 正确解析为可执行文档。

uprego@udv1320ku12:~$ ls /home/uprego/skype-4.0.0.8/ -thral
total 26M
-rw-r--r-- 1 uprego uprego 7.0K Jul 13 10:53 third-party_attributions.txt
drwxr-xr-x 2 uprego uprego 4.0K Jul 13 10:53 sounds
-rw-r--r-- 1 uprego uprego 161 Jul 13 10:53 skype.desktop
-rw-r--r-- 1 uprego uprego 453 Jul 13 10:53 skype.conf
-rwxr-xr-x 1 uprego uprego 26M Jul 13 10:53 skype
...

/home/uprego/skype-4.0.0.8/skype作为文档存在,具有可执行权限。

uprego@udv1320ku12:~$ strace /home/uprego/skype-4.0.0.8/skype
execve("/home/uprego/skype-4.0.0.8/skype", ["/home/uprego/skype-4.0.0.8/skype"],
    [/* 45 vars */]) = -1 ENOENT (No such file or directory)
...

它真的存在吗?

感谢您的关注。

答案1

execve()返回错误ENOENT时,它可能意味着多种情况:

  • 该程序不存在;
  • 程序本身存在,但它需要一个不存在的“解释器”。

ELF 可执行文件可以请求由另一个程序加载,其方式与#!/bin/somethingshell 脚本非常相似。

通常,动态链接的可执行文件请求/lib/ld-linux.so.2(或其他类似路径),负责在程序本身启动之前找到必要的共享库并将其加载到内存中。

在这种情况下,我猜你正试图在 64 位系统上运行 32 位 Skype,而你还没有安装 32 位glibc以及其他所需的库。(在 Debian 上应该是libc6:i386;在 Arch 上应该是lib32-glibc。)

要查看程序请求的确切路径,请使用readelf -l

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

$ readelf -l /tmp/skype-4.1.0.20/skype | grep interpreter
      [Requesting program interpreter: /lib/ld-linux.so.2]

相关内容