Rocky: No such file or directory

2025/2/25 实践总结Go

# Rocky: No such file or directory

今天遇到一个很诡异的问题,在 Rocky Linux 系统上明明看到可执行文件就在眼前,运行时却提示 “No such file or directory”,折腾了半天终于找到原因,记录一下过程。

# 问题现象:文件存在却 “消失” 了

事情是这样的,我在服务器上部署一个叫config-gray的程序,通过ll命令明明能看到文件存在,而且权限也是对的(rwxr-xr-x):

[root@xx config-gray]# ll config-gray
-rwxr-xr-x 1 root root 18061992 Feb 25 20:34 config-gray
1
2

但当我执行./config-gray时,却报了个让人费解的错:

[root@xx config-gray]# ./config-gray
bash: ./config-gray: No such file or directory
1
2

这就很离谱了 —— 文件明明在这儿,怎么会 “找不到”?

# 对比测试:CentOS 的错误更直白

为了排查问题,我在另一台 CentOS 7 服务器上试了下,同样的文件,报错信息稍微不一样:

[root@master config-gray]# ./config-gray
-bash: ./config-gray: /lib/ld-musl-x86_64.so.1: bad ELF interpreter: No such file or directory
1
2

这次的错误清晰多了:找不到/lib/ld-musl-x86_64.so.1这个 ELF 解释器。

# 原因分析:不是文件找不到,是依赖缺了

结合两个系统的报错,终于理清了头绪:

  • 第一个 Rocky 系统的 “文件不存在” 其实是个误导性错误。本质是系统找不到程序运行所需的动态链接器(解释器),导致操作系统无法加载程序,于是 “误以为” 文件不存在。
  • CentOS 的报错直接点出了核心:程序依赖musl libc的动态链接器(ld-musl-x86_64.so.1),但我的 Rocky 和 CentOS 系统默认装的是glibc,没有musl的相关库,所以找不到。

再看一下编译命令,问题可能出在这里:

CGO_ENABLED=1 go build -o config-gray -a -ldflags "-extldflags \"-static\"" -mod=vendor .
1

虽然加了-static参数想静态编译,但CGO_ENABLED=1开启了 CGO,可能导致编译时依赖了系统的musl libc(比如编译环境用了 Alpine 系统,默认是 musl),最终生成的二进制不是纯静态的,依然依赖 musl 的动态链接器。

# 解决方法:两种思路

# 1. 安装 musl 依赖(临时解决)

如果只是想让程序在现有系统运行,可以直接安装musl相关库:

  • Rocky/CentOS 7+ 可以通过 EPEL 源安装:

    # 先启用EPEL源
    yum install -y epel-release
    # 安装musl-libs
    yum install -y musl-libs
    
    1
    2
    3
    4

安装后再运行./config-gray,就能正常执行了。

# 2. 重新编译为纯静态程序(彻底解决)

更根本的方法是调整编译参数,生成不依赖系统 libc 的纯静态二进制:

# 关闭CGO,使用Go自带的标准库(不依赖系统libc)
CGO_ENABLED=0 go build -o config-gray -a -ldflags "-s -w" -mod=vendor .
1
2
  • CGO_ENABLED=0:禁用 CGO,避免依赖系统 libc(不管是 glibc 还是 musl)
  • -s -w:移除符号表和调试信息,减小二进制体积

# 总结

这次踩坑让我明白:遇到 “文件存在却提示找不到” 的情况,别光看文件本身,很大可能是程序依赖的动态链接库或解释器缺失。尤其是跨系统部署时,不同 Linux 发行版的 libc(glibc/musl)差异可能导致这类问题,编译时尽量用纯静态编译(CGO_ENABLED=0)能减少很多麻烦。