PowerShell 的解析模式:参数(命令)模式 vs. 表达式模式 [英] PowerShell's parsing modes: argument (command) mode vs. expression mode

查看:15
本文介绍了PowerShell 的解析模式:参数(命令)模式 vs. 表达式模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

谁能解释为什么当从 powershell 函数返回 $false 时,您无法使用比较运算符来确定函数是否返回了 $false,但是当您返回 $true 时,比较计算结果为 $true?

Can anyone explain why when returning $false from a powershell function you are unable use a comparison operator to determine if the function has returned $false but when you return $true the comparison evaluates to $true?

function boolean {
    return $false
}

boolean -eq $false

function boolean {
    return $true
}

boolean -eq $true

>>>False
>>>True

您可以通过将函数调用设置为变量来解决此问题,但我想知道是否有人可以解释幕后发生的事情?

You can work around this by setting the function call to a variable, but I was wondering if anyone could explain what is happening here under the hood?

function boolean {
    return $false
}

$bool = boolean 
$bool -eq $false

function boolean {
    return $true
}

$bool = boolean
$bool -eq $true

>>>True
>>>True

推荐答案

PowerShell 具有两种基本解析模式:

PowerShell has two fundamental parsing modes:

  • 参数模式,与传统的shell

  • 在参数模式下,第一个标记被解释为命令名称(例如 cmdlet 名称、函数名称或脚本或外部可执行文件的文件名),后跟一个空格分隔的列表参数.

表达式模式,其工作方式类似于传统的编程语言.

运行 Get-helpabout_Parsing 提供了对这些模式的介绍;简而言之,决定应用哪种模式的是第一个标记.
另请注意,给定语句可能由以任一模式解析的部分组成.

Running Get-help about_Parsing provides an introduction to these modes; in short, it is the first token that determines which mode is applied.
Also note that a given statement may be composed of parts that are parsed in either mode.

boolean -eq $false参数模式中解析,因为它的第一个标记看起来像一个命令名称(标识符可以是程序名称、cmdlet 名称、函数名称或别名).

boolean -eq $false is parsed in argument mode, because its first token looks like a command name (an identifier that could be a program name, cmdlet name, function name, or alias).

因此,-eq$false 被解释为 arguments(参数值)传递给函数 boolean.

Therefore, -eq and $false are interpreted as arguments (parameter values) to pass to function boolean.

由于您的 boolean 函数的定义方式不强制将值仅传递给 声明的 参数,因此参数被有效地忽略, 语句的结果是函数输出的任何内容($false$true).

Since your boolean functions are defined in a way that doesn't enforce passing values only to declared parameters, the arguments are effectively ignored, and the result of the statement is whatever the functions output ($false or $true).

Mike Shepard 的回答所示,您可以使函数强制使用仅声明的 参数(包括 none),带有 param() 块,用 [CmdletBinding()] 属性装饰(这使得该函数成为高级 函数),如果您无意中将参数传递给无参数boolean 函数,至少会导致错误.

As demonstrated in Mike Shepard's answer, you can make a function enforce use of only declared parameters (including none) with a param() block decorated with the [CmdletBinding()] attribute (which makes the function an advanced function), which would at least result in an error if you inadvertently passed arguments to the parameter-less boolean function.

您可以通过将函数调用设置为变量来解决此问题

You can work around this by setting the function call to a variable

$bool = boolean   # execute function and capture result in variable
$bool -eq $false  # use variable in the comparison 

这样做的原因是 -eq 语句 $ 开头 - 在这种情况下是变量引用 - 这会导致 PowerShell 解析在表达式模式下,-eq被识别为一个运算符$false被识别为它的RHS.

The reason this works is that the -eq statement starts with $ - a variable reference in this case - which causes PowerShell to parse in expression mode, where -eq is recognized as an operator and $false as its RHS.

但是,不需要这个中间步骤:

However, there is no need for this intermediate step:

强制将一段代码解释为表达式,请将其括在(...)中,分组运算符:

To force a piece of code to be interpreted as an expression, enclose it in (...), the grouping operator:

(boolean) -eq $false # Calls function 'boolean' and uses result as LHS of -eq

(...) 强制一个新的解析上下文(它本身以参数或表达式模式解析,同样取决于第一个标记)和 将结果视为表达式.然后允许将其用作更大表达式的一部分,例如作为 -eq 运算符的操作数,或作为命令参数.

(...) forces a new parsing context (which in itself is parsed in either argument or expression mode, again depending on the 1st token) and treats the result as an expression. which then allows its use as part of a larger expression, such as as an operand of the -eq operator, or as a command argument.

这篇关于PowerShell 的解析模式:参数(命令)模式 vs. 表达式模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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