在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




