适用场景:
Docker / Jenkins / Linux 容器中执行
.sh脚本失败报错:
env: 'bash\r': No such file or directory
一、问题现象(很多人都会遇到)
在 Docker 容器或 Jenkins 容器中,执行脚本:
bash
chmod +x install.sh
./install.sh
结果报错:
text
env: 'bash\r': No such file or directory
env: use -[v]S to pass options in shebang lines
看起来像是:
- bash 不存在?
- 权限不对?
- Jenkins / Docker 有问题?
👉 其实都不是。
二、根本原因(重点,一定要看)
✅ 真正原因:脚本是 Windows 换行符(CRLF)格式
Linux / Docker 使用的是:
- LF(\n) 换行
而 Windows 常见的是:
- CRLF(\r\n)
当脚本第一行是:
bash
#!/usr/bin/env bash\r
Linux 会把它理解成:
text
bash\r (一个不存在的命令)
于是就报了这个经典错误:
text
env: 'bash\r': No such file or directory
三、如何确认是不是这个问题(可选)
可以用下面命令查看隐藏字符:
bash
sed -n '1l' install.sh
如果看到:
text
#!/usr/bin/env bash\r$
那就 100% 确认是 CRLF 换行符问题。
四、解决办法(3 种,任选一种)
✅ 方法 1(最推荐):使用 sed 转换格式
bash
sed -i 's/\r$//' install.sh
然后再执行:
bash
./install.sh
✔ 通用
✔ 不依赖额外工具
✔ Docker / Jenkins 都适用
✅ 方法 2:使用 dos2unix(如果系统有)
bash
dos2unix install.sh
./install.sh
注意:不是所有容器里都有
dos2unix
✅ 方法 3:直接用 bash 执行(临时方案)
bash
bash install.sh
这种方式有时能绕过 shebang 问题,但不如前两种彻底
五、为什么很容易踩这个坑?
常见原因包括:
- 在 Windows 浏览器 中下载
.sh - 用 记事本 / VS Code(CRLF) 打开并保存
- 从 Windows 主机复制脚本到 Linux / Docker
- Jenkins 容器里直接粘贴脚本
👉 这些都会 自动把 LF 转成 CRLF。
六、推荐的「正确下载脚本姿势」
✅ 方式 1:直接 curl + bash(官方常用)
bash
curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash
✅ 方式 2:先下载,再处理换行符
bash
curl -o install.sh https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh
sed -i 's/\r$//' install.sh
bash install.sh
七、常见误区总结(新手必看)
| 错误操作 | 原因 |
|---|---|
sudo ./install.sh |
Docker 容器里通常没有 sudo |
一直 chmod +x |
权限不是根因 |
| 以为是 bash 没装 | 实际是换行符问题 |
| 以为 Jenkins 有 bug | 和 Jenkins 无关 |
八、一句话总结(可以直接记住)
env: 'bash\r'报错 ≠ bash 不存在
而是脚本是 Windows 格式(CRLF),
用sed -i 's/\r$//' 文件名即可解决。
九、写在最后(经验建议)
在 Linux / Docker / Jenkins 环境中:
.sh脚本 永远只用 LF- 不要用 Windows 记事本编辑
- 下载脚本尽量用
curl / wget