为什么在使用 -notMatch 条件验证参数时会满足此条件?



我正在使用Powershell验证传递到发布管道中的参数。我作为管道变量传递的参数是val1.这是我下面的代码:

if ("$(Value)" -notMatch "val1" -or "$(Value)" -notMatch "val2"){
Write-Host "$(Value) must be val1 || val2"
Write-Host "Value of param: "$(Value)""
exit 1
}

当我打印时,我的值是状态val1。为什么满足此条件?我想也许是因为它区分大小写,但是即使我修改条件以捕获确切的情况,它仍然得到满足。

如果你的变量应该只有val1val2,你必须使用-and而不是-or

if ("$(Value)" -notMatch "val1" -and "$(Value)" -notMatch "val2"){
Write-Host "$(Value) must be val1 || val2"
Write-Host "Value of param: "$(Value)""
exit 1
}

将其更改为

if ("$(Value)" -notMatch "val1" -and "$(Value)" -notMatch "val2"){
Write-Host "$(Value) must be val1 || val2"
Write-Host "Value of param: "$(Value)""
exit 1
}

注意:问题以及下面的代码中$(Value)Azure 管道宏,而不是PowerShell 变量引用,例如$Value。由于此类宏在 PowerShell 看到它之前已扩展为其值,因此将其括在"..."中(同样,如问题和下面的代码中所示)可确保如果值恰好包含空格或其他 PowerShell 元字符,则不会发生语法错误。

Shamrai Aleksander的有用答案解释了逻辑错误,但可能还有一个额外的问题:

  • 则表达式匹配运算符-match(及其-notmatch变体)默认匹配子字符串,因此"$(Value)"扩展到aval1,例如,也会错误地通过测试。

  • 对于集合文字全值比较,可以使用-in运算符(请注意,-contains仅在操作数颠倒时才具有相同的目的)及其变体,特别是在这种情况下-notin;使用-cnotin进行区分大小写的比较。

# Note: `$(Value)` is an *Azure pipeline macro (variable)*, which is expanded
#       *before* PowerShell sees the code.
#       In pure PowerShell code, the equivalent would be just `$Value`
if ("$(Value)" -notin 'val1', 'val2') {
Write-Error '$(Value) must be val1 || val2'
exit 1
}

我想也许是因为它区分大小写

请注意,默认情况下,所有PowerShell 运算符都不区分大小写(当它们对文本进行操作时);默认情况下,PowerShell 在大多数方面不区分大小写。

区分大小写的操作需要使用c前缀的变体,例如-cmatch

(可选)若要更清楚地发出意图信号,可以使用i前缀变体(如-imatch)发出不区分大小写的操作信号(所有i前缀变体的行为都类似于其非前缀基本形式)。

最新更新