如何在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 \ r1 \ a:术语'd:\ a \ r1 \ a'不被识别为a的名称cmdlet,函数,脚本文件或可操作程序.检查名称的拼写,或者是否包含路径,请验证该路径是正确的,然后重试.在D:\ a_temp \ 9de874c9-3acd-4a19-a4dd-763074d38e40.ps1:2 char:25
d:\a\r1\a : The term 'd:\a\r1\a' 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_temp\9de874c9-3acd-4a19-a4dd-763074d38e40.ps1:2 char:25
其中 d:\ a \ r1 \ a
显然是一个 $(System.DefaultWorkingDirectory)
,但是为什么它抛出此错误而不是仅仅串联字符串?
where obviously d:\a\r1\a
is a $(System.DefaultWorkingDirectory)
but why it throws this error instead of just concatenating the string?
推荐答案
注意:问题中的 $(System.DefaultWorkingDirectory)
是由Azure 在之前扩展的Azure Pipeline宏(变量),PowerShell可以看到该命令-不要与PowerShell自己的
Note: $(System.DefaultWorkingDirectory)
in the question is an Azure Pipeline macro (variable), expanded by Azure before PowerShell sees the command - it is not to be confused with PowerShell's own subexpression operator, $(...)
.
Shayki Abramczyk的答案提供了有效的解决方案,但让我提供一些背景信息:
Shayki Abramczyk's answer provides an effective solution, but let me provide some background information:
Azure通过宏 $(...)
执行的值扩展(替代)功能类似于预处理程序:它将引用的属性替换为其 verbatim值.
The value expansion (substitution) that Azure performs via macro $(...)
functions like a preprocessor: it replaces the referenced property 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"
假定Azure属性 ,则 转换为PowerShell看到的以下命令 /code>: turns into the following command seen by PowerShell, assuming that the value of Azure property 这是一个损坏的PowerShell命令,因为 This is a broken PowerShell command, because 因此,为了使PowerShell将Azure扩展值 Therefore, in order for PowerShell to recognize the Azure-expanded value 由于按天数扩展"值不需要进一步插值,因此 单引号是最佳选择(实际上,对于两个操作数): Since the expanded-by-Azure value needs no further interpolation, single quotes are the best choice (for both operands, actually): 实际上,您根本不需要字符串连接( In fact, you don't need string concatenation ( 您甚至可以将其与可扩展的PowerShell字符串( You could even combine that with expandable PowerShell strings ( 一个 caveat 类似于 One caveat re something like 在撰写本文时,定义变量 Azure帮助主题没有将其说明清楚,而是在 As of this writing, the Define variables Azure help topic doesn't spell it out, but bsed on the official comment in a GitHub docs issue, ambiguity is avoided as follows: 没有 转义机制;相反,没有引用Azure变量的 There is no escape mechanism; instead, 在典型情况下,PowerShell表达式不看起来像是Azure变量引用(例如, In the typical case, PowerShell expressions will not look like an Azure variable reference (e.g, 这篇关于如何在Azure DevOps中的Powershell内联脚本中正确连接字符串?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋! System.DefaultWorkingDirectory
的值是 d:\ a \ r1 \ a'
System.DefaultWorkingDirectory
is d:\a\r1\a'
:$SourceDirectoryPath = d:\a\r1\a + "/solution/project/bin/Debug"
d:\ a \ r1 \ a
-由于缺少引号-被解释为命令名称或路径;也就是说,尝试执行执行假定的可执行文件 d:\ a \ r1 \ a
-请参见d:\a\r1\a
- 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\r1\a
- see about_Parsing
. d:\ a \ r1 \ a
识别为 string ,您需要引用它-请参见d:\a\r1\a
as a string, you need to quote it - see about_Quoting_Rules
.$SourceDirectoryPath = '$(System.DefaultWorkingDirectory)' + '/solution/project/bin/Debug'
+
):+
) at all in your case:$SourceDirectoryPath = '$(System.DefaultWorkingDirectory)/solution/project/bin/Debug'
"..."
)结合使用,只要Azure扩展值不包含 $
前缀的标记PowerShell可能最终会解释(除非这是您的(异常)意图)."..."
), 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代码中,"1 + 1等于$(1 + 1)"
)."$(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)"
). $(...)
构造保持不变,因此通过传递到PowerShell.
$(...)
constructs that do not refer to Azure variables are left unchanged and therefore passed through to PowerShell. $($ foo.bar)
而不是$(foo.bar)
),尽管可能存在歧义: $(hostname)
是有效的PowerShell子表达式,如果 hostname
定义了Azure变量.$($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.