![为什么当我尝试运行可执行文件时它会说它不存在?](https://linux22.com/image/1252139/%E4%B8%BA%E4%BB%80%E4%B9%88%E5%BD%93%E6%88%91%E5%B0%9D%E8%AF%95%E8%BF%90%E8%A1%8C%E5%8F%AF%E6%89%A7%E8%A1%8C%E6%96%87%E4%BB%B6%E6%97%B6%E5%AE%83%E4%BC%9A%E8%AF%B4%E5%AE%83%E4%B8%8D%E5%AD%98%E5%9C%A8%EF%BC%9F.png)
我有一个编译程序,一个用于识别文本部分的标记器,它声称它不存在。
当我尝试通过命令行运行它时,我得到了这个:
user@place:/home/user/explicitRedactedPath$ ls tagger
tagger
user@place:/home/user/explicitRedactedPath$ ./tagger arg and other args
-bash: ./tagger: No such file or directory
此可执行文件必须由生成的脚本调用,这就是我遇到此问题的原因。此错误出现的原因是什么?我不知道如何修复它。
笔记:
- 操作系统是 Ubuntu
- 可执行文件是从另一台机器复制的
- 该文件确实具有执行权限(如果没有这些权限,它会给出正确的不允许消息)
- 我尝试将文件复制到其他位置(同样的问题)
- 我尝试用新副本替换该文件(同样的问题)
- 该文件确实存在。使用 pico 打开它时会显示一个包含二进制数据的文件。
答案1
程序是针对不兼容的架构编译的,导致程序无法执行。错误消息显示“不存在”而不是“无效的可执行文件”,这只是一个非常具有误导性的消息。
在目标机器上重新编译即可解决问题。
答案2
我遇到了与 OP 非常相似的问题(./lfm: Command not found.
当我正看着它时),这里的一些答案帮助我弄清楚了如何在不同系统上运行我的可执行文件而无需重新编译我会这样劝告过去的自己(如果我认为过去的我足够聪明,能够听从改变的话):
1)验证文件不是断开的链接,具有可执行权限,并且您没有尝试在 32 位操作系统上运行 64 位可执行文件(对我而言,file lfm
返回的lfm: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.9, not stripped
是 64 位;检查其中的uname -a
for输出x86_64
,以验证操作系统也是 64 位;i386
或i686
表示 32 位)(lfm
当然,在这些示例中用您的程序名称替换)。
2)ldd lfm
返回奇怪的not a dynamic executable
消息(而不是打印共享库依赖项),因此尝试readelf -l ./lfm | grep ld-linux
找出可执行文件期望在哪里找到 ld-linux,它是动态链接库的 linux 加载器(在我的情况下,返回[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
)。
3) 检查前一个命令指示的目录,表明指示的 ld-linux 文件不存在;将其从最初编译该程序的机器(或类似的系统,如果需要)复制到该目录。
4) 尝试再次运行原始程序。(对我来说有效。)此外,ldd ./lfm
现在应该可以工作了(但您始终可以使用它readelf -d ./lfm
来查看需要哪些库,然后验证它们是否可用。)
答案3
标记器可能是一个软链接,并且链接的目标不存在。像这样重现:
$ cp /usr/bin/ld .
$ ln -s ld fff
$ rm ld
$ ./fff
zsh: no such file or directory: ./fff
答案4
如果你不能重新编译,你可以考虑使用定势器将动态可执行文件映射到静态链接的可执行文件。请注意,我还没有亲自尝试过。