快速修复
# 一键:去掉行尾 CR
sed -i 's/\r$//' setup.sh && bash setup.sh
你会遇到什么
在 WSL/Linux 上执行 Windows 里写好的脚本,报 setup.sh: line 2: $'true\r': command not found,或 bash: ./setup.sh: /bin/bash^M: bad interpreter。报错里的 \r / ^M 是肉眼看不见的换行残留——用记事本/Windows 编辑器保存的脚本都会带上。
有的脚本"部分能跑、某几行突然 command not found",正是那些行尾带 CR 的命令。
本文路径:快速修复(30 秒一段命令)→ 一步步排查(可跳读)→ 原理与变体(症状/原因/证据)。赶时间直接跳到「快速修复」。
为什么会这样
Windows 文本文件用 CRLF(\r\n)结尾,Linux 只用 LF(\n):
- 命令名后带 CR:bash 把
true\r当成一个整体命令名 →$'true\r': command not found(CR 在 echo 参数里通常不报错,所以"时好时坏"); - shebang 行带 CR:
#!/bin/bash\r让内核去找/bin/bash\r(^M)这个解释器 →bad interpreter。
常见来源:记事本保存、Windows 编辑器默认 CRLF、git 检出配置不当(core.autocrlf)。
实测环境:WSL Ubuntu(bash 5.3.9),2026-08-29。
行尾的 CR( ,0x0D)在 Linux 文本处理里是普通字符,不是行分隔符:bash 解析一行脚本时把整行(含末尾 )当命令名,true ≠ true,于是报 $'true ': command not found。
shebang 是内核解析的:内核读第一行找解释器路径,#!/bin/bash 让内核去找名为 /bin/bash 的文件(不存在)→ bad interpreter。
两个环节的失败点不同:命令名错误发生在 shell 层(报 command not found),shebang 错误发生在内核 exec 层(报 bad interpreter)。
确定性推论:报错里带 $'... ' 或 ^M = CRLF 污染,sed -i 's/ $//' 或 dos2unix 一键清;git 检出后出现 = core.autocrlf/.gitattributes 行尾策略问题(见 git-crlf),修仓库配置而不是逐个文件改;
判断路径:file <脚本> 看 CRLF,cat -A 看 ^M$。
一步步来
1. 确认是不是 CRLF — 必做
file setup.sh
输出带 with CRLF 字样 → 就是这个问题(或 cat -A setup.sh 看行尾是否 ^M$)。
2. 去 CR — 必做
sed -i 's/\r$//' setup.sh
或 dos2unix setup.sh(未预装时先 sudo apt install dos2unix)。
3. 只有 shebang 行坏时 — 必做
bash setup.sh 显式调用解释器可绕过 shebang 解析(但正文 CR 仍在),根治还是去 CR。
4. 预防 — 必做
- 在 Linux 内编辑脚本(vi/nano);
- Windows 编辑器选 LF/Unix 换行(VS Code 右下角改);
- git 仓库统一
core.autocrlf策略; - 复制脚本后先
file setup.sh看一眼。
怎么确认修好了
bash setup.sh
不再报 command not found / bad interpreter 即成功。实测:sed -i 's/\r$//' 后脚本正常,exit=0;修复前正文 CR 报 $'true\r': command not found(exit=127)、shebang CR 报 bad interpreter(exit=126)。
其它环境的表现
| 环境 | 说明 |
|---|---|
| WSL/Linux 执行 | 一律去 CR:sed -i 's/\r$//' 或 dos2unix |
| Windows 编辑器保存 | 记事本默认 CRLF;VS Code 右下角切换 LF |
| git 检出 | core.autocrlf 配置不当会重新引入 CRLF |
| 部分命令报错 | 正是行尾带 CR 的命令,全量去 CR 即可 |
症状
在 WSL/Linux 上执行 Windows 里写好的脚本,报出两类典型错误:
$ bash setup.sh
setup.sh: line 2: $'true\r': command not found
$ ./setup.sh
bash: ./setup.sh: /bin/bash^M: bad interpreter: No such file or directory
- 报错里的
\r(或^M)是肉眼看不到的换行残留——用记事本/Windows 编辑器保存的脚本会带上。 - 有的脚本看起来「部分能跑」,某几行命令突然
command not found——正是那些行尾带 CR 的命令。
原因
- Windows 文本文件用 CRLF(\r\n)结尾,Linux 只用 LF(\n)。
- 命令名后带 CR:bash 把
true\r当成一个整体命令名 →$'true\r': command not found(CR 在 echo 参数里通常不报错,所以「时好时坏」)。 - shebang 行带 CR:
#!/bin/bash\r让内核去找/bin/bash\r(^M)这个解释器 →bad interpreter。 - 常见来源:记事本保存、Windows 编辑器默认 CRLF、git 检出配置不当(
core.autocrlf相关,见 git-crlf 条目)。
解法
- 快速修复(转换换行符):
sed -i 's/\r$//' setup.sh
# 或 dos2unix setup.sh
- 如果只有 shebang 行坏:
bash setup.sh显式调用解释器可绕过 shebang 解析(但正文 CR 仍在);根治还是去 CR。 - 预防:在 Linux 内编辑脚本(vi/nano);Windows 编辑器选 LF/Unix 换行;git 仓库统一
core.autocrlf策略(与 git-crlf 条目互补);复制脚本后先file setup.sh看一眼(显示with CRLF即中招)。
验证证据
- 本机(WSL Ubuntu 6.18.35.2,bash 5.3.9,2026-08-29):
- 实测 1(正文 CR):
printf '#!/bin/bash\ntrue\r\n'+bash→line 2: $'true\r': command not found,exit=127——与用户报错逐字一致。 - 实测 2(shebang CR):
#!/bin/bash\r+chmod +x+./执行 →/bin/bash^M: bad interpreter: No such file or directory,exit=126。 - 实测 3(修复):
sed -i 's/\r$//'后脚本正常,exit=0。 - dos2unix 未安装(示例命令如实给出,未实测)。
- 实测复现日志(2026-08-29)
适用工具 (1)
本问题方案已挂到下列工具的方案页——从工具页也能回到这里,双向可达。
bash · 外部工具来源与证据
素材来源:https://stackoverflow.com/questions/2920416/configure-bin-shm-bad-interpreter
← 编码代理与终端 问题域 | 问题货架 | 遇到其它问题?去 问题空间 提交求助卡