欢迎光临
我们一直在努力

Linux脚本换行符错误怎么修复

在 Windows 电脑上编辑好 Shell 脚本,上传到 Linux 服务器后,文件明明存在,执行时却提示 bad interpreter;有时还会出现 ^M 或 $'\r': command not found。

这类问题可能与脚本的换行格式有关。

如果文件使用了 CRLF 换行符,行尾多出来的回车字符可能影响解释器路径或命令解析。下面介绍如何确认问题、备份脚本、转换换行符,并检查修复结果。

1. 为什么脚本上传后会出现换行符错误?

文本文件中的换行并不只有一种格式。

换行格式字符表示常见使用场景
CRLF\r\n部分 Windows 编辑器保存的文本
LF\nLinux、Unix 环境中的文本

CRLF 比 LF 多了一个回车字符,也就是 \r。某些查看方式会把它显示为 ^M。

例如,脚本第一行原本是:

#!/bin/bash

当这行以 CRLF 结尾时,回车字符可能被包含在解释器路径中,导致系统无法找到对应的解释器。Linux 执行脚本时,脚本本身或指定的解释器不存在,都可能触发“没有那个文件或目录”一类错误。

常见报错可能包含:

/bin/bash^M: bad interpreter: No such file or directory

或者:

$'\r': command not found

具体提示取决于 Shell、脚本内容和启动方式。仅凭 No such file or directory,还不能直接认定是换行符问题。

另外,文件编码与换行格式是两回事:UTF-8 文件也可能使用 CRLF。

Linux脚本CRLF与LF换行符的区别

2. 操作环境与工具准备

本文以 Debian 12、Ubuntu 为例,处理对象是 ASCII 或 UTF-8 编码的 Bash 文本脚本。

如果文件被识别为二进制内容,或者使用 UTF-16 等其他编码,应先确认文件类型和编码,不要直接套用下面的转换步骤。

先安装检查工具:

apt-get update
apt-get install -y file dos2unix

以上安装命令使用 root 执行。如果使用具备 sudo 权限的普通账户,在命令前添加 sudo。

接下来,设置需要检查的脚本路径:

script_file='/opt/myjob/run.sh'

把 /opt/myjob/run.sh 替换为你的脚本实际绝对路径。后续命令沿用这个变量,请在同一个终端会话中操作。

检查和转换时,使用对脚本及其所在目录具有相应读写权限的账户。

如果需要独立的测试环境,可以使用莱卡云 Linux 云服务器进行操作。

查看官网购买链接: https://www.lcayun.com

9折优惠码:bloglcayun

3. 检查脚本是否包含 CRLF

3.1 查看文件信息

执行:

ls -l -- "$script_file"
file -- "$script_file"

对于使用 CRLF 的脚本,file 的输出可能包含:

ASCII text executable, with CRLF line terminators

其中,with CRLF line terminators 表示检测到了 CRLF 换行格式。

如果 ls -l 显示文件名后面带有 ->,说明当前路径是符号链接。先确认实际目标文件,再把 script_file 改为目标文件路径。

3.2 显示行尾的隐藏字符

执行:

LC_ALL=C sed -n '1,5l' "$script_file"

这里的 l 是小写字母 L,用于以可辨认的形式显示行内容及不可打印字符。

存在 CRLF 时,可能看到:

#!/bin/bash\r$
echo OK\r$

其中:

  • \r 表示回车字符。
  • $ 是这个查看命令显示的行尾标记,不是脚本中额外写入的字符。

这条命令只查看前五行。即使前五行正常,也不能排除后面的内容混用了其他换行格式。

3.3 检查整份文件

继续执行:

dos2unix -ih -- "$script_file"

这条命令只显示文件信息,不进行转换。输出示例:

     DOS    UNIX     MAC  BOM       TXTBIN  FILE
       2       0       0  no_bom    text    /opt/myjob/run.sh

重点看:

  • DOS: CRLF 换行数量。
  • UNIX: LF 换行数量。
  • MAC: 单独 CR 换行数量。

如果 DOS 大于 0,说明文件中包含 CRLF。如果 DOS 和 UNIX 都大于 0,说明文件混用了两种换行格式。

本文下面处理的是 CRLF。如果 MAC 列不为 0,或者文件编码不符合本文范围,建议先在编辑器中另存为 UTF-8 无 BOM、LF 换行,再继续检查。

4. 先备份,再转换为 LF

确认文件是需要处理的文本脚本后,执行:

backup_file="${script_file}.bak-$(date +%Y%m%d-%H%M%S-%N)"
cp -a -- "$script_file" "$backup_file" &&
dos2unix -- "$script_file"

这组命令会先在原目录生成带时间戳的备份,然后转换原脚本。

其中的 && 表示:只有备份命令成功,才继续执行转换。

dos2unix 默认采用原文件转换方式,所以备份应在转换前完成。

查看本次备份路径:

printf '备份文件:%s\n' "$backup_file"

如果转换提示失败或跳过文件,先处理对应原因,不要把“执行过命令”当作“转换成功”。

如需恢复本次备份,可以在同一个终端会话中执行:

cp -a -- "$backup_file" "$script_file"

这会用备份内容覆盖当前脚本。恢复前应确认,备份后没有需要保留的新修改。

5. 转换后如何确认修复成功?

5.1 重新检查换行格式

执行:

dos2unix -ih -- "$script_file"
LC_ALL=C sed -n '1,5l' "$script_file"

对于已经完成 CRLF 转 LF 的文件,应看到:

  • DOS 列变成 0。
  • 前五行的行尾不再出现 \r。

例如:

#!/bin/bash$
echo OK$

这里仍然显示的 $ 只是行尾标记,无需删除。

5.2 检查 Bash 语法

确认脚本使用 Bash 后,执行:

bash -n -- "$script_file" && printf 'Bash 语法检查通过\n'

bash -n 会读取并检查脚本语法,不执行其中的业务命令。语法检查通过,也不代表依赖程序、权限和运行环境都已满足。

5.3 按原来的方式验证运行

如果原来就是通过 Bash 手动执行,确认脚本内容和用途后,使用原业务账户、回到原工作目录运行:

bash -- "$script_file"
printf '退出状态:%s\n' "$?"

同时检查脚本日志和预期输出,确认任务实际完成。

如果原来通过 ./run.sh、Cron 或 systemd 启动,就应按原启动方式验证。直接执行 bash run.sh 成功,不能证明脚本首行的解释器设置和执行权限都正常。

最终以原启动方式下的执行结果为准,不要只看转换提示或语法检查。

Linux脚本换行符检查、备份转换与运行验证流程

6. 已经转成 LF,为什么还是报错?

换行符只是脚本无法运行的一种原因。如果确认 CRLF 已清除,可以继续按报错排查:

现象继续检查的方向
仍然提示 bad interpreter脚本第一行指定的解释器路径是否正确,解释器是否安装
提示 Permission denied直接执行时的文件执行权限、父目录访问权限、挂载选项
bash run.sh 成功,直接执行脚本失败脚本首行解释器声明和执行权限
手动执行成功,Cron 或 systemd 中失败执行用户、工作目录、环境变量和命令路径

不要为了处理换行符错误,直接把文件权限改成 777。权限设置无法消除文件中的 CRLF。

如果问题出现在定时任务或服务启动过程中,可以继续参考本站文章:

7. 如何避免下次上传后再次报错?

7.1 在编辑器中统一保存格式

编辑 Linux Shell 脚本时,建议使用:

  • 文件编码:UTF-8,无 BOM。
  • 换行格式:LF。

修改后保存文件,再上传到服务器。如果只修复服务器上的文件,却没有修改电脑上的源文件,下次上传时仍可能把 CRLF 带回来。

7.2 使用 Git 时设置脚本换行规则

如果脚本保存在 Git 仓库中,可以在项目根目录的 .gitattributes 中加入:

*.sh text eol=lf

这条规则针对匹配的 .sh 文件启用文本规范化,并指定工作区使用 LF 换行。已有 .gitattributes 时,应补充规则,保留原来的其他配置。

需要注意:

  • 这条规则不匹配没有 .sh 扩展名的脚本。
  • 添加规则不等于当前工作区中的所有旧文件都会立即被重写。
  • 已有问题文件仍需修复,并检查 Git 差异后按项目流程提交。

8. 结语

Linux 脚本出现 ^M、bad interpreter 或 $'\r': command not found 时,可以先检查是否混入了 CRLF 换行符。

处理时按顺序完成:确认格式、备份文件、转换为 LF、检查语法、按原方式验证运行。

如果换行格式已经正常,就继续检查解释器路径、权限和运行环境。同时把电脑上的源文件保存为 UTF-8 无 BOM、LF 格式,可以减少重新上传后再次出现同类问题的情况。

赞(0)
未经允许不得转载:莱卡云 » Linux脚本换行符错误怎么修复