编码代理与终端 · 收录于 2026-08-29 · 适用 1 工具 ✓ 实测验证

bash 脚本报 $'\r': command not found / bad interpreter: /bin/bash^M——Windows 换行符(CRLF)混入

已验证 2026-08-29bash 报 $'\r' command not found 是 Windows CRLF 换行符混入脚本——sed -i 's/\r//' 一行修复。

快速修复

# 一键:去掉行尾 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 的命令。

原因

  1. Windows 文本文件用 CRLF(\r\n)结尾,Linux 只用 LF(\n)。
  2. 命令名后带 CR:bash 把 true\r 当成一个整体命令名 → $'true\r': command not found(CR 在 echo 参数里通常不报错,所以「时好时坏」)。
  3. shebang 行带 CR:#!/bin/bash\r 让内核去找 /bin/bash\r(^M)这个解释器 → bad interpreter。
  4. 常见来源:记事本保存、Windows 编辑器默认 CRLF、git 检出配置不当(core.autocrlf 相关,见 git-crlf 条目)。

解法

  1. 快速修复(转换换行符):
   sed -i 's/\r$//' setup.sh
   # 或 dos2unix setup.sh
  1. 如果只有 shebang 行坏:bash setup.sh 显式调用解释器可绕过 shebang 解析(但正文 CR 仍在);根治还是去 CR。
  2. 预防:在 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 · 外部工具

来源与证据

收录 验证 ✓ 实测验证适用 1 工具
方案含本地实测或来源可复核的解法;未实测项已在文中如实标注。

素材来源:https://stackoverflow.com/questions/2920416/configure-bin-shm-bad-interpreter

← 编码代理与终端 问题域 | 问题货架 | 遇到其它问题?去 问题空间 提交求助卡