Bash 中调用 Cmd 脚本的难点分析

在流水线中不可避免地会遇到通过 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 编码的内容,这样日志存储时就不会乱码。

  1. Bat 脚本可能需要改成 UTF-8 编码。
  2. Bat 脚本中运行切换代码页指令 chcp 65001

另外,echo 命令在遇到某些汉字或标点时容易发生故障,可以考虑更换其他输出方式。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容