如何在 Azure DevOps 的 Powershell 内联脚本中正确连接字符串? [英] How to correctly concatenate string in Powershell inline script in Azure DevOps?

查看:21
本文介绍了如何在 Azure DevOps 的 Powershell 内联脚本中正确连接字符串?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试连接字符串以构建路径:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆