在流水线中不可避免地会遇到通过 Bash 调用 Windows Cmd(Bat)脚本的场景,这里总结了一些难点和解决方案。
Bat 脚本必须是 CRLF 换行符
以这个脚本为例:
@echo off
echo "中"
使用 CRLF 换行符时可以正常执行,但换成 LF 换行符就会报错:
'cho' 不是内部或外部命令,也不是可运行的程序
或批处理文件。
当遇到脚本在本机(Windows)执行正常,但到了流水线中异常时,就要考虑是否是因为 Git 取出文件后换行符变了。
Bash 调用 Bat 脚本
Jenkins Windows Agent 支持运行 Bash 脚本,并且 Bash 脚本中可以调用 Bat 脚本。
类似效果可以在 Git Bash 中试验:
./hello.bat # 可以运行
cmd //c hello.bat # 也可以运行
不能用 start hello.bat,这样新开窗口不会等待。start /wait 也不行,这样 Job 会卡住,一直等待。
Bat 文件字符集
Bat 文件的字符集会影响控制台输出中文的显示。
当 Bat 文件字符集和 Cmd 代码页不一致时,就会导致显示错误。
-
当代码页936时,文件要
GBK,否则会显示成
文件gbk,代码页65001 -
当代码页65001时,文件要
UTF-8时,,否则显示错误。
代码页65001,文件gbk
主动切换代码页
调用 chcp 命令可以主动切换代码页。
切换代码页会在当前进程中持续生效。
当实质上发生代码页变化时,会导致当前窗口出现清屏行为。
构建日志乱码问题分析
CI 平台一般按照 UTF-8 来接收和存储日志。Linux 构建机通常不会发生编码错误问题,但 Windows 构建机容易遇到编码错误问题。
这里经过了日志存储、Bash、Cmd、Exe 四层,很容易导致汉字乱码。
实验表明,在 Windows Git Bash 中直接调用 Bat、Exe 命令时,Mintty 会自己处理好字符集问题,但如果是在流水线中则容易出现错误。
建议在流水线中显式设置代码页为 UTF-8,让 Bat、Exe 输出 UTF-8 编码的内容,这样日志存储时就不会乱码。
- Bat 脚本可能需要改成 UTF-8 编码。
- Bat 脚本中运行切换代码页指令
chcp 65001。
另外,echo 命令在遇到某些汉字或标点时容易发生故障,可以考虑更换其他输出方式。

