Shell Gitlab CI:访问环境变量

Shell Gitlab CI:访问环境变量,shell,gitlab,gitlab-ci,Shell,Gitlab,Gitlab Ci,考虑以下gitlab-ci.yml: ... variables: var_A: 'Hello' before_script: - export var_B="World" step1: stage: build script: - chmod u+x run.sh && source run.sh 假设run.sh包含以下脚本: echo $var_A echo $var_B 我注意到在CI运行管道后,var_A解析为“Hello”,但是调用echo

考虑以下gitlab-ci.yml:

...
variables:
  var_A: 'Hello'
before_script:
  - export var_B="World"
step1:
  stage: build
  script:
    - chmod u+x run.sh && source run.sh
假设run.sh包含以下脚本:

echo $var_A
echo $var_B

我注意到在CI运行管道后,
var_A
解析为“Hello”,但是调用
echo$var_B
不会在屏幕上打印任何内容。这里到底发生了什么?有没有办法访问shell脚本中的var_b

如果一个进程启动了一个子进程,而这个子进程设置了环境变量,那么这些变量只在子进程中和子进程的子进程中可见,它们永远不会传播到父进程,父进程也无法轻松访问其子进程的环境

对于GitLab CI运行程序,运行程序将启动一个子进程来运行脚本指令,即shell(默认情况下为
/bin/sh
)。当您更改该shell中的环境时,此更改仅对shell和shell的所有子进程可见(例如,您正在执行的命令)

但是,在脚本之前运行脚本指令的shell不必与之后运行脚本指令的shell相同,通常这是两个独立的shell;尤其是因为您的
before\u脚本是全局脚本,所以它对所有作业都运行一次,而所有作业都可以并行运行,因此都需要自己的shell。在一个shell中对环境所做的更改在以后的其他shell中运行的代码将看不到

作为解决方法,您可以使用以下文件:

variables:
  var_A: 'Hello'
before_script:
  - echo 'export var_B="World"' > somefile.env
step1:
  stage: build
  script:
    - source somefile.env
    - chmod u+x run.sh && source run.sh
顺便说一下,如果您
source
脚本文件,它不需要是可执行的,因此不需要
chmod
。如果您希望以
/run.sh
的形式运行脚本,则需要该脚本。区别在于
source
在当前shell中执行脚本代码,而
/run.sh
将创建一个子shell并在那里执行代码。在子shell中运行时,
run.sh
将看到您的所有环境,但对它的更改对
run.sh
及其调用的任何进程都是私有的,而如果您执行
源代码运行,这些更改将传播到主shell。sh

这已经存在,并且仍然是开放的