智睿享
白蓝主题五 · 清爽阅读
首页  > 网络优化

换行编码标准:别让看不见的字符搞砸你的代码协作

你有没有遇到过这样的情况:明明在本地测试好好的脚本,推送到服务器后突然报错?或者同事打开你写的配置文件,发现每一行都莫名其妙地连在一起?问题很可能就出在“换行符”这个不起眼的细节上。

换行符不是统一的

很多人以为按下回车产生的“换行”在所有系统里都一样,其实不然。不同的操作系统使用不同的换行编码标准:

  • Windows 使用 CRLF(\r\n,即回车+换行)
  • Linux 和 macOS(现代版本)使用 LF(\n,仅换行)
  • 老版 macOS(9 及之前)曾用 CR(\r,仅回车)

这些字符在文本编辑器里通常不可见,但程序会严格解析。比如一个在 Windows 上生成的 shell 脚本,如果换行符是 CRLF,拿到 Linux 环境执行时,解释器可能识别不了 \r,导致命令找不到,报错类似 command not found: \r

Git 项目中的典型坑

团队协作中,开发者分布在不同操作系统,这个问题更明显。你在 Mac 上写了个 JSON 配置文件,提交到仓库,同事在 Windows 上拉下来,Git 自动把 LF 转成了 CRLF。他再改点内容提交,又可能转回去。来回几次,diff 里全是整行变更,根本看不出实际改了啥。

Git 提供了 core.autocrlf 设置来缓解:

# Windows 用户
git config --global core.autocrlf true

# Mac/Linux 用户
git config --global core.autocrlf input

设置为 input 时,提交时自动转成 LF,检出时不转换,适合类 Unix 系统。而 true 表示检出时转成 CRLF,提交时转回 LF。

如何查看和转换换行符

cat -A 可以看清换行符真相:

cat -A script.sh

输出中,$ 代表 LF,^M$ 代表 CRLF。如果你看到一堆 ^M,基本可以确定是 Windows 风格换行符混入了 Unix 环境。

批量转换可以用 dos2unixsed

dos2unix broken-script.sh
# 或者
sed -i 's/\r$//' problematic-file.txt

统一标准才是长久之计

最好的办法是在项目初期就定下换行编码标准。现在很多项目根目录放个 .editorconfig 文件,明确指定:

root = true

[*.sh]
end_of_line = lf

[*.json]
end_of_line = lf

主流编辑器都支持 .editorconfig,能自动按规则保存文件。配合 CI 流程做换行符检查,能提前拦截问题。

别小看这一两个字符的差异,它们能在你毫无防备的时候,让自动化脚本全线崩溃。早一点关注换行编码标准,少走很多弯路。