powershell - 如何在 Azure DevOps 的 Powershell 内联脚本中正确连接字符串?
问题描述
我尝试连接字符串以构造路径:
$SourceDirectoryPath = $(System.DefaultWorkingDirectory) + "/solution/project/bin/Debug"
$TargetFilePath = $(System.DefaultWorkingDirectory) + "/solution/project/bin/Debug/" + $(Release.ReleaseName) +$(Release.EnvironmentName)
但不是将字符串连接起来,而是第二行出现错误:
d:\a\r1\a :术语“d:\a\r1\a”未被识别为 cmdlet、函数、脚本文件或可运行程序的名称。检查名称的拼写,或者如果包含路径,请验证路径是否正确并重试。在 D:\a_temp\9de874c9-3acd-4a19-a4dd-763074d38e40.ps1:2 char:25
显然d:\a\r1\a
是 a$(System.DefaultWorkingDirectory)
但为什么它会抛出这个错误而不是仅仅连接字符串?
解决方案
tl;博士
在PowerShell 看到生成的命令之前扩展的是Azure ;如果扩展值被 PowerShell 视为字符串,则必须将其括在引号( ) 中:$(System.DefaultWorkingDirectory)
$(...)
'$(...)'
使用
$(...)
(Azure 宏语法)将 Azure 变量的 逐字值嵌入到 PowerShell 最终解释的命令文本中。- 注意:Azure的宏语法 -在 PowerShell 看到生成的命令文本之前进行评估- 不要与PowerShell自己的子表达式运算符
$(...)
.
- 注意:Azure的宏语法 -在 PowerShell 看到生成的命令文本之前进行评估- 不要与PowerShell自己的子表达式运算符
对于字符串值,这意味着您必须根据情况将宏用引号括起来,以使其在 PowerShell 代码中以语法方式工作,其中
'...'
-quoting(单引号)是最好的:'$(System.DefaultWorkingDirectory)'
Shayki Abramczyk 的回答提供了一个有效的解决方案,但让我提供一些背景信息:
Azure 通过宏语法 ( )执行的变量扩展(替换)$(...)
功能类似于预处理器:它将引用的变量替换为其逐字值。
您需要确保此逐字值在目标命令的上下文中在语法上有效。
如目前所写:
$SourceDirectoryPath = $(System.DefaultWorkingDirectory) + "/solution/project/bin/Debug"
变成PowerShell 看到的以下命令,假设 Azure 属性的System.DefaultWorkingDirectory
值为d:\a\r1\a
:
$SourceDirectoryPath = d:\a\r1\a + "/solution/project/bin/Debug"
这是一个损坏的 PowerShell 命令,因为d:\a\r1\a
- 由于缺少引用 - 被解释为命令名称或路径;也就是说,尝试执行假定的可执行文件d:\a\r1\a
-see about_Parsing
。
因此,为了让 PowerShell 将 Azure 扩展值识别d:\a\r1\a
为字符串,您需要引用它- 请参阅about_Quoting_Rules
.
由于按 Azure 扩展的值不需要进一步插值,因此单引号是最佳选择(实际上对于两个操作数):
$SourceDirectoryPath = '$(System.DefaultWorkingDirectory)' + '/solution/project/bin/Debug'
实际上,在您的情况下,您根本不需要字符串连接 ( +
):
$SourceDirectoryPath = '$(System.DefaultWorkingDirectory)/solution/project/bin/Debug'
您甚至可以将其与可扩展的 PowerShell 字符串 ( "..."
) 结合使用,只要 Azure 扩展的值不包含$
PowerShell 最终可能解释的 -prefixed 标记(除非这是您的(不寻常的)意图)。
一个警告类似于(将Azure扩展值与"$(System.DefaultWorkingDirectory)/$projectRoot/bin/Debug"
PowerShell 变量引用混合)是Azure 的 宏语法($(...)
字符串(例如,在纯 PowerShell 代码中)。"1 + 1 equals $(1 + 1)"
在撰写本文时,Define variables Azure 帮助主题并未详细说明,但根据GitHub 文档问题中的官方评论,避免了歧义,如下所示:
没有逃生机制;相反,
$(...)
不引用 Azure 变量的构造保持不变,因此传递给 PowerShell。在典型情况下,PowerShell 表达式看起来不像Azure 变量引用(例如,
$($foo.bar)
而不是$(foo.bar)
),尽管假设可能存在歧义:如果定义了 Azure 变量$(hostname)
,它是一个有效的 PowerShell 子表达式,可能会被 Azure 抢占。hostname
- 在这种极端情况下,解决方案是避免使用内联脚本,而是将代码放在外部脚本文件中。
推荐阅读
- sql-server - 如何将 SAS 创建的表移动到 sql server 中的不同文件组
- mysql - 自定义 TYPO3 v10 扩展中缺少列 UID
- r - 使用动态变量名进行变异
- javascript - 构建 /@types/lodash/common/object.d.ts (1188,142) 时出现 lodash 错误:'(' 预期
- apache-spark - 在使用另一个数据帧调用的 UDF 中过滤数据帧
- c++ - How to programmatically differentiate between dvd or mini dvd disk inserted?
- android - Android BLE 广告不能超过 20 字节
- c# - 如何从 API 中获取版本详细信息
- javascript - reactjs面包屑功能和太多渲染
- google-chrome - Clickjacked every non secure site (http) by hobfadbig.com