You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

在CentOS Docker容器运行WSL编译的Go程序报错:/bin/sh: <program>: not found

可能的原因及解决办法

这种问题我碰到过好几次,大概率是下面几个原因之一,挨个排查应该能解决:

1. Go程序的编译目标平台不匹配

你在WSL里编译的程序,可能默认的目标平台和CentOS容器的平台不一致——比如不小心编译成了Windows可执行文件(虽然WSL是Linux子系统,但如果GOOS环境变量被设成了windows就会出问题),或者架构不匹配(比如WSL是x86_64,容器却是ARM架构)。

排查方法:在WSL里执行go env GOOS GOARCH,看输出是不是linux amd64(对应x86_64的CentOS容器)。

解决办法:编译时明确指定目标平台,确保生成Linux下的可执行文件:

CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o <program-name> ./path/to/main.go

CGO_ENABLED=0还能生成静态编译的二进制,避免后续依赖库的问题。

2. 程序不在容器的当前工作目录,或挂载路径错误

你执行./<program-name>时,当前目录可能不是你挂载卷的目录,导致找不到程序。比如你把WSL的编译输出目录挂载到了容器的/app,但exec进去后默认在/目录,那./program-name肯定找不到。

排查方法

  • 先确认Docker启动容器时的挂载命令是否正确,比如:
    docker run -d -v /home/your-wsl-user/build-output:/app --name my-centos centos
    
  • 进入容器后,用ls /app看看里面有没有你的程序。

解决办法

  • 要么进入容器后切换到挂载目录:cd /app && ./<program-name>
  • 要么直接用绝对路径运行:/app/<program-name>

3. 程序没有可执行权限

WSL里的文件权限和Docker容器的权限映射可能有问题,导致编译出来的程序在容器里没有执行权限。

排查方法:进入容器后,在程序所在目录执行ls -l,看程序的权限位有没有x(比如-rwxr-xr-x才是可执行的)。

解决办法:在WSL里给程序添加可执行权限:

chmod +x /path/to/your/program-name

之后再重新挂载或重启容器(一般挂载的卷是实时同步的,不用重启)。

4. 动态编译的程序缺少依赖库

如果你的Go程序是动态编译的(默认CGO_ENABLED=1),那它可能依赖CentOS容器里没有的系统库(比如某些glibc版本差异,或者缺失的依赖),这时候系统会提示“not found”(其实是找不到依赖库,不是程序本身)。

排查方法:在WSL里用ldd <program-name>查看程序的依赖库,然后在CentOS容器里检查这些库是否存在。比如执行ldd /app/<program-name>,如果显示某个库not found,就是这个问题。

解决办法:用静态编译的方式生成程序,也就是编译时加上CGO_ENABLED=0,这样程序会把所有依赖打包进去,不依赖系统库:

CGO_ENABLED=0 go build -o <program-name> ./path/to/main.go

5. WSL与Docker的文件系统挂载兼容性问题

如果你用的是Windows路径(比如C:\Users\xxx\build)而不是WSL原生路径(比如/mnt/c/Users/xxx/build)挂载到容器,可能会出现文件权限异常或者文件损坏的情况,导致容器识别不了可执行文件。

解决办法:挂载时使用WSL的原生路径,比如在WSL终端里执行Docker命令,用/home/your-user/build这样的路径,而不是Windows的盘符路径。


内容的提问来源于stack exchange,提问作者Rohith

火山引擎 最新活动