在脚本中设置变量
Azure DevOps Services | Azure DevOps Server 2022 - Azure DevOps Server 2019
在管道中使用 PowerShell 和 Bash 脚本时,如果能够设置可在将来的任务中使用的变量,则通常会很有帮助。 新设置的变量在同一任务中不可用。
如果你要执行的操作不受某个任务的支持(例如调用自定义 REST API 和分析响应)时,则脚本非常有用。
你将使用 task.setvariable
日志记录命令在 PowerShell 和 Bash 脚本中设置变量。
注意
部署作业对输出变量使用不同的语法。 若要详细了解部署作业中对输出变量的支持,请参阅部署作业。
若要在管道中使用带有条件的变量,请参阅指定条件。
关于 task.setvariable
添加包含 task.setvariable
的变量时,以下任务可以按照宏语法 $(myVar)
使用该变量。 默认情况下,变量仅适用于同一作业中的任务。 如果添加参数 isoutput
,则用于调用变量的语法会更改。 请参阅设置用于同一作业的输出变量。
设置包含值 foo
的变量 myVar
。
- bash: |
echo "##vso[task.setvariable variable=myVar;]foo"
读取变量 myVar
:
- bash: |
echo "You can use macro syntax for variables: $(myVar)"
设置变量属性
task.setvariable
命令包含用于将变量设置为机密、输出变量和只读的属性。 可用属性包括:
variable
= 变量名称(必需)issecret
= 布尔值(可选,默认值为 false)isoutput
= 布尔值(可选,默认值为 false)isreadonly
= 布尔值(可选,默认值为 false)
若要在下一阶段中使用变量,请将 isoutput
属性设置为 true
。 若要引用 isoutput
设置为 true 的变量,请包含任务名称。 例如 $(TaskName.myVar)
。
将变量设置为只读后,下游任务无法覆盖该变量。 将 isreadonly
设置为 true
。 将某个变量设置为只读会使该变量不可变,因而可增强安全性。
将变量设置为机密
当 issecret
设置为 true 时,变量的值将另存为机密并从日志中屏蔽。
注意
Azure Pipelines 在向管道日志发出数据时会努力屏蔽机密,因此你可能会在输出和日志中看到未设置为机密的其他变量和数据掩码。
设置机密变量 mySecretVal
。
- bash: |
echo "##vso[task.setvariable variable=mySecretVal;issecret=true]secretvalue"
获取机密变量 mySecretVal
。
- bash: |
echo "##vso[task.setvariable variable=mySecretVal;issecret=true]secretvalue"
- bash: |
echo $(mySecretVal)
bash 中的机密变量输出。
输出变量的级别
有四种不同类型的输出变量,其语法各不相同:
- 在同一作业中设置的不带
isoutput
参数的输出变量。 若要引用这些变量,请使用宏语法。 示例:$(myVar)
。 - 在同一作业中设置的带有
isoutput
参数的输出变量。 若要引用这些变量,请包含任务名称。 示例:$(myTask.myVar)
。 - 在将来的作业中设置的输出变量。 若要引用这些变量,请使用
dependency
语法在variables
节中引用变量。 - 在将来的阶段中设置的输出变量。 若要引用这些变量,请使用
stageDependencies
语法在variables
节中引用变量。
注意
如果将来的阶段或作业依赖于设置变量的阶段或作业,则将来的阶段或作业只能访问输出变量。 若要将输出变量设为可访问,请确保下一阶段或作业依赖于创建变量的阶段或作业。 如果多个阶段或作业需要使用相同的输出变量,请使用 dependsOn
条件来建立此依赖项。
设置用于同一作业的输出变量
在同一作业中使用输出变量时,无需使用 isoutput
属性。 默认情况下,该变量将可用于同一作业中的下游步骤。 但是,如果你确实要添加 isoutput
属性,则需要使用任务名称引用该变量。
此处的脚本在不指定 isoutput
的情况下设置同作业输出变量 myJobVar
,并在指定 isoutput=true
的情况下设置 myOutputJobVar
。
jobs:
- job: A
steps:
- bash: |
echo "##vso[task.setvariable variable=myJobVar]this is the same job"
- bash: |
echo "##vso[task.setvariable variable=myOutputJobVar;isoutput=true]this is the same job too"
name: setOutput
此脚本获取同作业变量 myJobVar
和 myOutputJobVar
。 请注意,添加 isoutput=true
后,用于引用输出变量的语法会更改。
jobs:
- job: A
steps:
- bash: |
echo "##vso[task.setvariable variable=myJobVar]this is the same job"
- bash: |
echo "##vso[task.setvariable variable=myOutputJobVar;isoutput=true]this is the same job too"
name: setOutput
- bash: |
echo $(myJobVar)
- bash: |
echo $(setOutput.myOutputJobVar)
设置要在将来的作业中使用的输出变量
跨作业使用输出变量时,请使用 dependencies
引用这些变量。 用于在将来的作业或阶段中访问输出变量的语法,根据该变量的设置者和使用者之间的关系而变化。 在依赖关系中了解每种案例。
首先,设置输出变量 myOutputVar
。
jobs:
- job: A
steps:
- bash: |
echo "##vso[task.setvariable variable=myOutputVar;isoutput=true]this is from job A"
name: passOutput
接下来,在将来的作业中访问 myOutputVar
并将变量输出为 myVarFromJobA
。 若要使用 dependencies
,需要使用设置了输出变量的以往作业名称来设置将来作业的 dependsOn
属性。
jobs:
- job: A
steps:
- bash: |
echo "##vso[task.setvariable variable=myOutputVar;isoutput=true]this is from job A"
name: passOutput
- job: B
dependsOn: A
variables:
myVarFromJobA: $[ dependencies.A.outputs['passOutput.myOutputVar'] ]
steps:
- bash: |
echo $(myVarFromJobA)
设置要在将来的阶段中使用的输出变量
可以跨管道中的阶段使用输出变量。 可以使用输出变量将有用的信息(例如生成的输出的 ID)从一个阶段传递到下一个阶段。
设置带有 isoutput
属性的变量后,可以在后续阶段中使用任务名称和 stageDependencies
语法引用该变量。 详细了解依赖关系。
输出变量仅在下一个下游阶段中可用。 如果多个阶段使用相同的输出变量,请使用 dependsOn
条件。
首先,设置输出变量 myStageVal
。
steps:
- bash: echo "##vso[task.setvariable variable=myStageVal;isOutput=true]this is a stage output variable"
name: MyOutputVar
然后,在将来的阶段中,将输出变量 myStageVal
映射到阶段、作业或任务范围的变量,例如 myStageAVar
。 请注意,映射语法使用运行时表达式 $[]
,并使用阶段名称 (A
) 和作业名称 (A1
) 跟踪从 stageDependencies
到输出变量的路径,以完全限定变量。
stages:
- stage: A
jobs:
- job: A1
steps:
- bash: echo "##vso[task.setvariable variable=myStageVal;isOutput=true]this is a stage output variable"
name: MyOutputVar
- stage: B
dependsOn: A
jobs:
- job: B1
variables:
myStageAVar: $[stageDependencies.A.A1.outputs['MyOutputVar.myStageVal']]
steps:
- bash: echo $(myStageAVar)
如果值包含换行符,你可以将换行符转义,而代理会自动取消转义:
steps:
- bash: |
escape_data() {
local data=$1
data="${data//'%'/'%AZP25'}"
data="${data//$'\n'/'%0A'}"
data="${data//$'\r'/'%0D'}"
echo "$data"
}
echo "##vso[task.setvariable variable=myStageVal;isOutput=true]$(escape_data $'foo\nbar')"
name: MyOutputVar
FAQ
我的输出变量未呈现。 出什么问题了吗?
有多个原因会导致输出变量不显示。
- 使用
isoutput
设置的输出变量在同一作业中不可用,而仅在下游作业中可用。 - 根据使用的变量语法,设置输出变量值的变量在运行时可能不可用。 例如,采用宏语法 (
$(var)
) 的变量会在任务运行之前进行处理。 相比之下,采用模板语法的变量会在运行时进行处理 ($[variables.var]
)。 在设置输出变量时,你通常想要使用运行时语法。 有关变量语法的详细信息,请参阅定义变量。 - 表达式中可能包含多余的空格。 如果变量未呈现,请检查
isOutput=true
两侧是否存在多余的空格。
可以通过为依赖项添加变量,然后打印该变量,对管道作业或阶段的 dependencies
输出进行故障排除。 例如,在此管道作业 A
中设置输出变量 MyTask
。 第二个作业 (B
) 取决于作业 A
。 一个新变量 deps
用于保存作业依赖项的 JSON 表示形式。 作业 B
中的第二步使用 PowerShell 输出 deps
,以便你可以看到作业依赖项。
trigger:
- '*'
pool:
vmImage: 'ubuntu-latest'
jobs:
- job: A
steps:
- script: |
echo "##vso[task.setvariable variable=MyTask;isOutput=true]theoutputval"
name: ProduceVar
- job: B
dependsOn: A
variables:
varFromA: $[ dependencies.A.outputs['ProduceVar.MyTask'] ]
deps: $[convertToJson(dependencies)] # create a variable with the job dependencies
steps:
- script: echo $(varFromA) #
- powershell: Write-Host "$(deps)"