dos2unix 是什么
Windows 文本用 CRLF(回车加换行)作为行尾,Linux 只用 LF。dos2unix 负责把 CRLF 转换成 LF,unix2dos 做反向转换,两者都是原地修改文件。脚本从 Windows 传上来后执行报错、配置里多出看不见的字符、git diff 显示整个文件都被改动,多数都源于这类行尾差异。
基本信息
| 适用平台 | Linux/Unix(dos2unix 包,多数发行版需单独安装) |
|---|---|
| 命令语法 | dos2unix [-k] 文件... 与 unix2dos [-k] 文件... |
| 常用选项 | -k 保留原文件的修改时间与属主 -f 强制转换(包含被判定为二进制的文件) |
| 探测方式 | file 或 file -i 查看行尾与编码;cat -A 可看到行尾的 ^M(后跟 $) |
| 默认行为 | 原地写回文件,会保留原文件的权限;转换时自动跳过被识别为二进制的文件 |
典型使用场景
- 脚本执行报错 bad interpreter:从 Windows 编辑后 shebang 行带了 CR
- 配置解析失败:行尾多了 CR,键值对匹配不上
- 代码提交前统一:混用行尾会让 diff 与合并变得难以阅读
- 批量修复目录内的脚本:find 加 -exec 一次处理
- 导出文件交付前:根据目标平台统一成 LF 或 CRLF
常用示例
常用示例
file deploy.sh # 探测是否含 CRLF
cat -A deploy.sh | head -n 3 # 直接看到行尾的 ^M 符号
dos2unix -k deploy.sh # 转换并保留原时间戳
unix2dos -k conf.ini # 反向:转成 CRLF
find . -name '*.sh' -exec dos2unix -k {} + # 批量修脚本
find . -name '*.sh' -print0 | xargs -0 dos2unix -k现象与根因对照
| 现象 | 根因 | 处理 |
|---|---|---|
| /bin/bash^M: bad interpreter | shebang 行尾部有 CR | dos2unix 转换后重新执行 |
| 配置项读不到值 | 行尾 CR 被当成值的一部分 | 转换行尾并复核配置解析结果 |
| git diff 显示整文件改动 | 行尾或编码不一致 | 统一行尾后再提交,必要时配 .gitattributes |
| 编译报 stray \r 之类错误 | 源码文件行尾不统一 | 转换行尾并确认编辑器保存格式 |
| 中文乱码 | 是编码问题不是行尾问题 | 用 iconv 转换编码,别用 dos2unix |
bash: ./deploy.sh: /bin/bash^M: bad interpreter 是 CRLF 最典型的报错,dos2unix 一条命令就能解决。排查时先 file 看行尾,再 cat -A 确认 CR 的位置,比盲改文件高效。
dos2unix 默认原地覆盖写入,批量处理前先备份或纳入版本控制。转换后建议用 git diff 或 diff 复核一遍:确认改动只有行尾,而没有连带改动编码或内容。这个过程不可逆,原文件一旦被覆盖,之前的行尾信息就找不回来了,所以要留下备份或提交记录。
file 的判定基于内容统计特征,不是绝对结论:纯英文内容会被报成 us-ascii 或 ASCII text,至于是不是带 CRLF 要看后面对行尾的描述。拿不准时用 cat -A 直接看行尾有没有 ^M,这比反复试转换更快也更确定。