代码 Windows 脚本丢到 Linux CI 报错 env: 'bash\r':CRLF 换行符的检测、修复与根治

2026-09-03 21:04:31

Windows 脚本丢到 Linux CI 报错:env: 'bash\r'? 治 CRLF 换行符

本地脚本在 Windows 上跑得好好的,提交到 CI 容器里执行却报错:

env: 'bash\r': No such file or directory

这类问题绝大多数是换行符。Windows 编辑器(记事本、VS Code 默认 CRLF)保存的脚本到了 Linux,行尾多一个 \r,shebang 那行变成 #!/usr/bin/env bash\r,系统会去找名为 bash\r 的解释器,自然找不到。

现象

  • 核心报错:env: 'bash\r': No such file or directory,或 -bash: ./install.sh: /bin/bash^M: 坏的解释器: 无法执行
  • 明明 ls 能看到文件,却报找不到解释器

注意:这跟「没加执行权限」或「bash 没装」无关,别在那些方向上浪费时间。

确认是不是换行符问题

三种快速检测:

  • cat -A script.sh:行尾出现 ^M$ 就是 CRLF(^M\r 的可视化)。纯 LF 只显示 $
  • sed -n '1l' script.sh:第一行若显示 #!/usr/bin/env bash\r$ 即命中。
  • file script.sh:输出含 with CRLF line terminators 即命中。
  • 若怀疑还有 UTF-8 BOM:grep -r $'\xEF\xBB\xBF' . --include='*.sh'

修复

  • 首选 sed(所有发行版都有,容器的 base image 里不一定装了 dos2unix):
sed -i 's/\r$//' script.sh
  • 有 dos2unix 时:
dos2unix script.sh
  • 改完再执行:
chmod +x script.sh
./script.sh

长期预防

  • 仓库根放 .gitattributes,强制 LF:
*.sh text eol=lf
* text=auto eol=lf

.gitattributes 是仓库级生效,比个人 core.autocrlf 配置可靠。

  • 编辑器统一:VS Code 右下角把 CRLF 切到 LF,或加 .editorconfig
end_of_line = lf
  • 已入库的历史文件执行 git add --renormalize . 统一。
  • CI 加一道 lint 拦截,防止回归:
grep -rUl $'\r' *.sh && exit 1

参考:本地脚本好好的,云上执行报错:bash\r 问题排查

复制全文 生成海报 Shell 运维 脚本

推荐文章

程序员茄子在线接单