GitLab CI/CD中$PWD等内置变量无法正常赋值使用的问题
GitLab CI中$PWD等运行时变量无法赋值给自定义变量的问题解决
问题核心拆解
你遇到的所有异常,本质都是GitLab CI变量的展开阶段差异导致的,分点解释如下:
1. $PWD无法赋值给自定义变量的原因
GitLab CI的变量展开分两个关键阶段:
- 配置解析阶段:GitLab服务器解析
.gitlab-ci.yml时处理变量,这个阶段只能访问GitLab预定义的流水线级变量(比如$CI_COMMIT_SHORT_SHA、$CI_PROJECT_DIR)。 - shell运行阶段:runner执行job的script脚本时,才会生成
$PWD、$HOME这类shell运行时变量。
你在variables块里定义ONE: $PWD、FOUR: $PWD时,属于配置解析阶段,此时$PWD还未生成,所以展开后是空值。
2. 单引号包裹的$PWD不展开的原因
在GitLab CI的script中,单引号会强制阻止所有变量展开——不管是GitLab预定义变量还是shell变量,单引号内的内容会被当作纯字符串直接输出,所以echo '$PWD/my/dist/folder'会原封不动输出$PWD。
3. $TWO、$THREE能正常展开的原因
$TWO是你自定义的静态变量,属于配置解析阶段就能获取到的值,所以$THREE: $TWO能正常展开,因为两个变量都在同一阶段处理。
解决方案
方案1:用GitLab预定义变量替代$PWD
GitLab提供了$CI_PROJECT_DIR预定义变量,它的值和$PWD完全一致(都是runner上的仓库工作目录),而且属于流水线级变量,在配置解析阶段就能访问。
修改你的变量定义:
# 全局变量 variables: ONE: value: $CI_PROJECT_DIR expand: true # job级变量 build-test-deploy: variables: FOUR: value: $CI_PROJECT_DIR expand: true # rules级变量 rules: - if: $CI_COMMIT_BRANCH == "development" variables: EIGHT: $CI_PROJECT_DIR
方案2:在script中动态赋值自定义变量
如果需要使用非$CI_PROJECT_DIR的其他shell运行时变量,可以在job的script里动态定义,而非在variables块中:
script: # 动态定义自定义变量 - ONE=$PWD - FOUR=$PWD - echo $ONE - echo $FOUR # 展开单引号里的变量,改用双引号 - echo "$PWD/my/dist/folder"
方案3:正确用引号控制变量展开
- 要展开变量:使用双引号或不加引号(注意变量值含空格时必须用双引号)
- 要保留变量名不展开:使用单引号
比如把echo '$PWD/my/dist/folder'改成:
echo "$PWD/my/dist/folder" # 正常展开$PWD
修正后的完整配置示例
default: image: csi:0.1 variables: ONE: value: $CI_PROJECT_DIR expand: true TWO: value: "hello world" expand: true THREE: value: $TWO expand: true FLAGS: value: '-al' expand: true LS_CMD: value: 'ls "$FLAGS" $$TMP_DIR' expand: true .branch-detection: rules: - if: ($CI_COMMIT_BRANCH != "main" && $CI_COMMIT_BRANCH != "development") when: never stages: - deploy build-test-deploy: variables: FOUR: value: $CI_PROJECT_DIR expand: true FIVE: value: "hi" expand: true SIX: value: '$FIVE, there' expand: true stage: deploy extends: - .branch-detection script: - echo $PWD - echo "$PWD/my/dist/folder" - echo $ONE - echo $TWO - echo $THREE - echo $FOUR - echo $FIVE - echo $SIX - echo $SEVEN - echo $EIGHT - echo $NINE - echo $FLAGS - echo $LS_CMD rules: - if: $CI_COMMIT_BRANCH == "development" variables: FIVE: "My value changed in the rules, did SIX?" SEVEN: $TWO EIGHT: $CI_PROJECT_DIR NINE: 'this is variable six, enclosed in double quotes "$SIX"'
内容的提问来源于stack exchange,提问作者Bob Ramsey
相关产品推荐
相关产品推荐

