写点什么

容器中 sh 脚本明明存在,为何会报"no such file or directory"的错误?

作者:大伟
  • 2023-11-15
    北京
  • 本文字数:686 字

    阅读完需:约 2 分钟

容器中sh脚本明明存在,为何会报"no such file or directory"的错误?

小伙伴碰到一起奇怪的事故,从 gitlab 上拉取的 docker 镜像项目,在本地开发机上进行 docker build 后,启动容器会报错如下:

exec /app/run.sh : no such file or directory
复制代码

 /app/run.sh 文件是 ENTRYPOINT 启动的,注释掉 ENTRYPOINT,直接进入容器后可以看到 /app/run.sh 好好在那儿,文件的可执行权限也没有问题。那么问题在哪里?

 

其实这个问题很简单,但由于容器启动时的错误信息不全,产生了误导,让人误以为找不到 sh 脚本文件。

 

如果先启动容器,在容器内再手工执行 /app/run.sh,会看到报错信息略有不同。实际报错的是 sh 脚本的第一句:

#!/bin/bash
复制代码

 那么是因为容器内缺失 /bin/bash 解释器吗?也不是,基础镜像没有问题,/bin/bash 好好的存在。


最关键的是,同样的 git 项目拉取到的 sh 脚本和 Dockerfile 在另外一台开发机上进行镜像编译和运行是没有问题的。

 

仔细观察,发现 sh 脚本文件在不同的机器上,有一点点不同:换行符。


出问题的开发机上,脚本换行符是 Windows 换行符 CRLF,所以这个脚本进入 Docker 容器中,第一行变成了:

#!/bin/bash【看不见的CRLF】
复制代码

 那执行脚本的时候,LF 会被认为是 Linux 换行符,而解释器名称就成了”/bin/bashCR“,肯定找不到,所以就会报错"no such file or directory"。


这个报错的真实含义是”找不到脚本的解释器“,而不是找不到脚本本身。

 

那么为什么脚本文件的换行符被改变为 CRLF 呢,其实是 git 的 core.autocrlf 特性搞的鬼。参考 https://blog.upx8.com/3184


为了避免这种问题,有两个建议:

1,所有的开发机上,统一 git 的 autocrlf 设置,避免其为 true。

2,VSCode 上安装 code-eol 插件,显式的体现出每个文件的换行符,这样可以比较直观的察觉到问题。

 

用户头像

大伟

关注

码龙战BUG于野。 2020-05-21 加入

还未添加个人简介

评论

发布
暂无评论
容器中sh脚本明明存在,为何会报"no such file or directory"的错误?_git_大伟_InfoQ写作社区