如何在 Azure DevOps 的 Powershell 内联脚本中正确连接字符串? [英] How to correctly concatenate string in Powershell inline script in Azure DevOps?
问题描述
我尝试连接字符串以构建路径:
I try to concatenate string to construct a path:
$SourceDirectoryPath = $(System.DefaultWorkingDirectory) + "/solution/project/bin/Debug"
$TargetFilePath = $(System.DefaultWorkingDirectory) + "/solution/project/bin/Debug/" + $(Release.ReleaseName) +$(Release.EnvironmentName)
但不是将字符串连接起来,而是第二行出现错误:
but instead of getting string concatenated I get error for the second line:
d:a 1a : 术语 'd:a 1a' 不被识别为 a 的名称cmdlet、函数、脚本文件或可运行的程序.检查名称的拼写,或者如果包含路径,请验证路径是正确的,然后再试一次.在D:a_temp9de874c9-3acd-4a19-a4dd-763074d38e40.ps1:2 char:25
d:a 1a : The term 'd:a 1a' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again. At D:a_temp9de874c9-3acd-4a19-a4dd-763074d38e40.ps1:2 char:25
显然 d:a
1a
是 $(System.DefaultWorkingDirectory)
但为什么它会抛出这个错误而不是仅仅连接字符串?>
where obviously d:a
1a
is a $(System.DefaultWorkingDirectory)
but why it throws this error instead of just concatenating the string?
推荐答案
tl;dr
Azure 扩展了 $(System.DefaultWorkingDirectory)
在 PowerShell 看到结果命令之前;如果扩展的 $(...)
值要被 PowerShell 视为字符串,则必须将其括在引号中('$(...)'
):
It is Azure that expands $(System.DefaultWorkingDirectory)
before PowerShell sees the resulting commands; if the expanded $(...)
value is to be seen as a string by PowerShell, it must be enclosed in quotes ('$(...)'
):
使用
$(...)
(Azure 宏语法) 嵌入Azure 变量的逐字值 在 PowerShell 最终解释的命令文本中.
Using
$(...)
(Azure macro syntax) embeds the Azure variable's verbatim value in the command text that PowerShell ends up interpreting.
- 注意:Azure 的宏语法 - 在 PowerShell 看到结果命令文本之前进行评估 - 不要与 PowerShell 自己的 子表达式运算符,
$(...)
.
- Note: Azure's macro syntax - which is evaluated before PowerShell sees the resulting command text - is not to be confused with PowerShell's own subexpression operator,
$(...)
.
对于 string 值,这意味着您必须用引号将宏括起来,以使其在语法上工作PowerShell 代码,对于 '...'
-quoting(单引号)最好:'$(System.DefaultWorkingDirectory)'
For string values this means that you situationally have to surround the macro with quotes in order to make it work syntactically in PowerShell code, for which '...'
-quoting (single-quoting) is best: '$(System.DefaultWorkingDirectory)'
Shayki Abramczyk 的回答 提供了一个有效的解决方案,但让我提供一些背景信息:
Shayki Abramczyk's answer provides an effective solution, but let me provide some background information:
Azure 通过宏语法 ($(...)
) 执行的变量扩展(替换)就像一个预处理器:它替换引用的变量及其逐字价值.
The variable expansion (substitution) that Azure performs via macro syntax ($(...)
) functions like a preprocessor: it replaces the referenced variable with its verbatim value.
您需要确保此逐字值在目标命令的上下文中在语法上有效.
You need to make sure that this verbatim value works syntactically in the context of the target command.
目前所写:
$SourceDirectoryPath = $(System.DefaultWorkingDirectory) + /solution/project/bin/Debug"
变成下面的命令被PowerShell看到,假设Azure属性System.DefaultWorkingDirectory
的值为d:a
1a代码>:
turns into the following command seen by PowerShell, assuming that the value of Azure property System.DefaultWorkingDirectory
is d:a
1a
:
$SourceDirectoryPath = d:a
1a + "/solution/project/bin/Debug"
这是一个损坏的 PowerShell 命令,因为 d:a
1a
- 由于缺少引号 - 被解释为 命令名称或路径;也就是说,尝试执行假定的可执行文件d:a
1a
- 请参阅about_Parsing
.
This is a broken PowerShell command, because d:a
1a
- due to lack of quoting - is interpreted as a command name or path; that is, an attempt is made to execute putative executable d:a
1a
- see about_Parsing
.
因此,为了让 PowerShell 将 Azure 扩展值 d:a
1a
识别为字符串,您需要引用它 - 请参阅about_Quoting_Rules
.
Therefore, in order for PowerShell to recognize the Azure-expanded value d:a
1a
as a string, you need to quote it - see about_Quoting_Rules
.
由于 Azure 扩展值不需要进一步插值,单引号是最好的选择(实际上对于两个操作数):
Since the expanded-by-Azure value needs no further interpolation, single quotes are the best choice (for both operands, actually):
$SourceDirectoryPath = '$(System.DefaultWorkingDirectory)' + '/solution/project/bin/Debug'
实际上,在您的情况下,您根本不需要字符串连接 (+
):
In fact, you don't need string concatenation (+
) at all in your case:
$SourceDirectoryPath = '$(System.DefaultWorkingDirectory)/solution/project/bin/Debug'
您甚至可以将其与可扩展的 PowerShell 字符串("..."
)结合使用,只要 Azure 扩展的值不包含 $
-PowerShell 最终可能会解释的前缀标记(除非这是您的(不寻常的)意图).
You could even combine that with expandable PowerShell strings ("..."
), as long as the Azure-expanded value doesn't contain $
-prefixed tokens that PowerShell could end up interpreting (unless that is your (unusual) intent).
一个警告类似于"$(System.DefaultWorkingDirectory)/$projectRoot/bin/Debug"
(将 Azure 扩展值与 PowerShell 变量引用混合) 是 Azure 的 宏语法 ($(...)
) 看起来与 PowerShell 自己的 子表达式运算符,通常 - 但不完全 - 用于将 表达式 嵌入可扩展字符串中(例如,在纯 PowerShell 代码中,1 + 1 等于 $(1 + 1)"
).
One caveat re something like "$(System.DefaultWorkingDirectory)/$projectRoot/bin/Debug"
(mixing an Azure-expanded value with a PowerShell variable reference) is that Azure's macro syntax ($(...)
) looks the same as PowerShell's own subexpression operator, which is typically - but not exclusively - used in order to embed expressions in expandable strings (e.g., in pure PowerShell code, "1 + 1 equals $(1 + 1)"
).
在撰写本文时,定义变量 Azure 帮助主题没有详细说明,而是基于 GitHub 文档问题中的官方评论,避免歧义如下:
As of this writing, the Define variables Azure help topic doesn't spell it out, but based on the official comment in a GitHub docs issue, ambiguity is avoided as follows:
没有转义机制;相反,不引用 Azure 变量的
$(...)
构造保持不变,因此传递到 PowerShell.
There is no escape mechanism; instead,
$(...)
constructs that do not refer to Azure variables are left unchanged and therefore passed through to PowerShell.
在典型情况下,PowerShell 表达式不会看起来像 Azure 变量引用(例如,$($foo.bar)
而不是 $(foo.bar)
),但假设可能存在歧义:$(hostname)
,这是一个有效的 PowerShell 子表达式,如果 hostname
Azure 变量已定义.
In the typical case, PowerShell expressions will not look like an Azure variable reference (e.g, $($foo.bar)
rather than $(foo.bar)
), though hypothetically there can be ambiguity: $(hostname)
, which is a valid PowerShell subexpression, could be preempted by Azure if a hostname
Azure variable were defined.
- 在这种极端情况下,解决方案是避免使用内联脚本,而是将代码放在外部脚本文件中.
- In such a corner case, the solution is to avoid use of an inline script and instead place the code in an external script file.
这篇关于如何在 Azure DevOps 的 Powershell 内联脚本中正确连接字符串?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!