PowerShell的解析模式:参数(命令)模式与表达模式

时间:2018-02-13 21:46:44

标签: powershell parsing syntax

任何人都可以解释为什么当从powershell函数返回$ false时,你无法使用比较运算符来确定函数是否返回$ false但是当你返回$ true时,比较结果为$ true?

function boolean {
    return $false
}

boolean -eq $false

function boolean {
    return $true
}

boolean -eq $true

>>>False
>>>True

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

function boolean {
    return $false
}

$bool = boolean 
$bool -eq $false

function boolean {
    return $true
}

$bool = boolean
$bool -eq $true

>>>True
>>>True

2 个答案:

答案 0 :(得分:5)

PowerShell将-eq视为传递给“boolean”函数的参数的名称。

要看到这一点,你可以将函数调用放入parens:

function boolean {
    return $false
}

(boolean) -eq $false

function boolean {
    return $true
}

(boolean) -eq $true

或者,您可以将其设为高级功能,以便在缺少参数(-eq)时出错:

function boolean {
[CmdletBinding()]
Param()
    return $false
}

boolean -eq $false

function boolean {
[CmdletBinding()]
Param()
    return $true
}

boolean -eq $true

答案 1 :(得分:4)

PowerShell有 两种基本解析模式

  • 参数模式,其作用类似于传统 shell

    • 在参数模式下,第一个标记被解释为命令名称 (例如cmdlet名称,函数名称或可执行文件的文件名),紧随其后通过参数的空格分隔列表
  • 表达式模式,与传统的编程语言类似。

正在运行Get-help about_Parsing介绍了这些模式;简而言之, 第一个令牌决定了应用哪种模式。
另请注意,给定语句可能由在任一模式下解析的部分组成。

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

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

由于boolean函数的定义方式不会强制仅将值传递给声明的参数,因此参数实际上是忽略,并且语句的结果是函数输出的任何内容($false$true)。

正如Mike Shepard's answer所示,您可以使函数强制使用仅使用param() [CmdletBinding()]块修饰的声明参数(包括 none )属性,如果您无意中将参数传递给无参数boolean函数,则至少会导致错误。

  

您可以通过将函数调用设置为变量

来解决此问题
$bool = boolean   # execute function and capture result in variable
$bool -eq $false  # use variable in the comparison 

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

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

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

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

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