Jenkins构建Flutter时Git路径检测失败,git_exists变量无法设为true
问题背景
在Jenkins上构建Flutter项目时,flutter/bin目录下的shared.bat脚本通过git rev-parse HEAD检测Git是否存在,但git_exists变量始终无法被设为true,最终触发"Unable to find git in your PATH"错误——尽管git命令实际能正常运行。
核心原因
这是Windows批处理的变量延迟扩展机制导致的:
批处理默认会在执行()包裹的代码块前,预解析所有%变量%引用。也就是说,你在FOR循环里给git_exists赋值为true后,代码块内和外部读取的依然是初始的false值,因为预解析已经完成,不会实时更新变量内容。从你的执行输出里echo 'After2 : false'也能看出来——循环内输出的还是初始值,而非赋值后的true。
解决方案
方案1:开启变量延迟扩展
在批处理脚本开头添加SETLOCAL EnableDelayedExpansion,并把读取变量的%git_exists%替换成!git_exists!,这样变量会在执行时实时解析,而非预解析。
修改后的shared.bat代码:
REM 开启变量延迟扩展 SETLOCAL EnableDelayedExpansion REM Check that git exists and get the revision SET git_exists=false 2>NUL ( PUSHD "%flutter_root%" FOR /f %%r IN ('git rev-parse HEAD') DO ( SET git_exists=true SET revision=%%r ) POPD ) REM If git didn't execute we don't have git. Exit without /B to avoid retrying. if !git_exists! == false echo Error: Unable to find git in your PATH. && EXIT 1 REM 关闭延迟扩展(可选,若后续逻辑不需要) ENDLOCAL
对应的Jenkins测试脚本修改:
bat ''' chcp 1251 REM 开启延迟扩展 SETLOCAL EnableDelayedExpansion SET git_exists=false 2>NUL ( PUSHD "%flutter_root%" FOR /f %%r IN ('git rev-parse HEAD') DO ( SET git_exists=true echo 'After2 : !git_exists!' SET revision=%%r ) POPD ) echo 'After1 : !git_exists!' REM 关闭延迟扩展 ENDLOCAL flutter doctor '''
方案2:不依赖变量,直接用执行结果判断
如果不想开启延迟扩展,可以跳过git_exists变量,直接通过revision变量是否被赋值来判断git是否可用——只要git命令执行成功,revision就会被赋值为当前HEAD的哈希值。
修改后的shared.bat代码:
REM Check that git exists and get the revision SET revision= 2>NUL ( PUSHD "%flutter_root%" FOR /f %%r IN ('git rev-parse HEAD') DO ( SET revision=%%r ) POPD ) REM 如果revision未被赋值,说明git命令执行失败 if not defined revision echo Error: Unable to find git in your PATH. && EXIT 1
验证
修改后重新执行Jenkins流水线,git_exists会被正确设为true(方案1),或通过revision变量的存在性正确判断git状态(方案2),从而避免触发错误。
内容的提问来源于stack exchange,提问作者Мартынов Олег

