UNIX/Linux和Windows系统在文本文件的换行符表示上存在根本差异:
\n
,ASCII码0x0A)\r\n
,ASCII码0x0D 0x0A)\r
,ASCII码0x0D)这种差异源于早期的打字机和计算机终端: - 回车(CR):将打印头移动到行首 - 换行(LF):将纸张向上移动一行 - Windows继承自DOS,DOS继承自CP/M,CP/M的设计者为了简化硬件实现采用了CRLF - UNIX选择了更简洁的LF表示
跨平台文件交换问题:
开发中的常见问题:
# UNIX脚本在Windows下可能报错
/bin/bash^M: bad interpreter: No such file or directory
(这里的^M就是Windows添加的CR字符)
Linux/Unix下:
file filename.txt # 显示文件类型和换行符信息
cat -A filename.txt # 显示不可见字符(^M表示CR,$表示LF)
od -c filename.txt | head # 以八进制显示文件内容
Windows下:
Get-Content -Raw filename.txt | Select-String -Pattern "\r\n"
Linux/Unix下:
# UNIX转DOS(添加CR)
sed -i 's/$/\r/' unixfile.txt
# 或使用dos2unix/unix2dos工具
unix2dos file.txt # 转换为Windows格式
dos2unix file.txt # 转换为UNIX格式
# 使用tr命令
tr -d '\r' < winfile.txt > unixfile.txt
Windows下:
PowerShell:
# 转换为UNIX格式
(Get-Content winfile.txt) -join "`n" | Set-Content unixfile.txt
# 转换为Windows格式
(Get-Content unixfile.txt) | Set-Content winfile.txt
跨平台工具:
core.autocrlf
配置Git提供了自动换行符转换功能:
# 提交时转换为LF,检出时转换为CRLF(适合Windows开发者)
git config --global core.autocrlf true
# 提交和检出都保留原样(适合跨平台项目)
git config --global core.autocrlf input
# 完全禁用转换(不推荐)
git config --global core.autocrlf false
# 显示当前配置
git config --global core.autocrlf
还可以通过.gitattributes
文件设置每仓库规则:
* text=auto
*.sh text eol=lf
*.bat text eol=crlf
项目统一:
开发环境配置:
文件传输:
脚本编写:
#!/bin/bash
而非#!/bin/bash^M
Q1:为什么我的Shell脚本在Windows编辑后无法在Linux运行?
A:Windows添加了CR字符,使用dos2unix
转换或配置Git自动转换。
Q2:如何批量转换项目中的换行符? A:
# 递归转换当前目录下所有.sh文件
find . -name "*.sh" -exec dos2unix {} \;
Q3:Git显示所有文件都被修改了,但实际内容没变?
A:这是换行符自动转换导致的,配置合适的core.autocrlf
或.gitattributes
。
理解并正确处理换行符差异,可以避免许多跨平台开发中的诡异问题。