gpt4 book ai didi

带有字符串数组的powershell函数开关参数

转载 作者:行者123 更新时间:2023-12-03 00:06:34 24 4
gpt4 key购买 nike

我正在努力理解以下函数的输出

function testApp
{
param(
[string] $appName,
[switch] $sw = $false,
[string[]] $test,
[string[]] $test2
)

Write-Host $appName - $sw - $test - $test2
}
  • testApp -appName "TestApp"-sw $true -test "one", "two"-test2 "three","four"

  • 输出: TestApp - True - 一二 - 三四
  • testApp -appName "TestApp"-sw $true -test "one", "two"

  • 输出: TestApp - True - 一二 - True

    第一个输出符合预期。但是当我没有通过它时,我无法理解为什么 test2 数组的第二个输出具有“True”。任何人都可以帮助我理解这种行为的原因吗?谢谢。

    最佳答案

    通过 Lee_Dailey 总结和补充对该问题的有益评论, Matthewmclayton :
    [switch] PowerShell 中的参数(也就是其他 shell 中的标志):

    switch 参数意味着 $true对比 $false通过他们的存在 在调用中:例如,传递 -sw自身发出信号 $true , 而省略 -sw信号$false .

  • 为了传递以编程方式确定的值,可以显式传递 bool 值;例如:-sw:$var
  • 注意所需的 : 跟在开关名称后面,它告诉 PowerShell bool 值属于开关参数;没有它,PowerShell 认为该值是一个位置参数,用于不同的参数(见下文)。
  • 警告:命令可能会解释 -sw:$false与省略 -sw 不同;一个突出的例子是使用公共(public)参数-Confirm:$false覆盖有效 $ConfirmPreference值(value)。
  • 如果您需要在自己的代码中进行这种区分,请使用 $PSBoundParameters.ContainsKey('sw') -and -not $sw检测 -sw:$false案件。
  • 不分配默认值 到开关参数变量:虽然技术上可行,约定是开关默认为 $false (无论如何,这是一个 [switch] 实例的默认值);即 [switch]参数应始终具有选择加入逻辑。

  • 一个 [switch]参数变量有效地表现得像一个 bool 值 在大多数情况下:
  • 也就是说,你可以说 if ($sw) { ... } , 例如。
  • 如果您需要显式访问包装的 bool 值,请访问 .IsPresent属性(property) (请注意,属性名称有点令人困惑,因为在 -sw:$false 调用中,开关仍然存在,但它的值,如 .IsPresent 所反射(reflect)的,是 $false )。
  • where .IsPresent 的示例需要使用 bool 值作为隐式数组索引,特别是模拟三元条件 [1]:('falseValue', 'trueValue')[$sw.IsPresent] ;没有 .IsPresent ,有效 bool 值不会被识别,也不会自动映射到索引 0 (来自 $false)或 1 (来自 $true)。


  • 最终,您的问题是您认为 $true-sw 的参数,而它成为隐式绑定(bind)到 -test2 的位置参数范围。
    [switch]参数永远不需要值,因此下一个参数成为一个单独的位置参数 - 除非您通过在开关名称后面加上 : 来明确表明该参数属于该开关。 ,如上所示。 [2]

    PowerShell 中传递的位置与命名参数:

    术语说明 :为了概念清晰,术语参数用于指代传递给声明参数的值。这避免了根据情况使用参数来指代接收值与给定值的语言结构的歧义。
  • 命名参数传递 (binding) 是指将目标参数名称显式地放置在参数之前(通常用空格分隔,但也可以和/或由 : 分隔);例如,-AppName foo .
  • 命名参数的传递顺序无关紧要。
  • 位置(未命名)参数传递 指传递一个参数而不在它前面加上其目标参数的名称;例如,foo .
  • 传递是位置性的,因为其他未命名参数之间的相对位置(顺序)决定了隐含的目标参数。
  • [switch]参数是个异常(exception),因为它们:
  • 通常仅通过名称传递( -sw ),暗示值 $true ,如果传递了一个值,则需要 :将名称与值分开。
  • 从不支持位置绑定(bind)。
  • 您可以将命名传递与位置传递结合使用 ,在这种情况下,首先绑定(bind)命名参数,然后考虑位置参数(按顺序)以绑定(bind)到尚未绑定(bind)的参数。
  • 默认情况下,PowerShell 函数是简单的函数。 为了控制位置绑定(bind),使用 [CmdletBinding()]和/或 [Parameter()]属性是必要的(见下文),它总是将一个简单的函数变成一个高级函数 .
  • 将一个简单的函数变成高级函数具有更大的行为影响(主要是有益的),详细信息请参见 this answer .
  • 默认情况下,PowerShell 函数接受任何参数的位置参数 (除了 [switch] 类型的那些),按照参数声明的顺序 .
  • 此外,简单函数接受未声明参数的任意附加参数,这些参数收集在自动 $args 中。数组变量。
  • 防止你的函数默认接受任何位置参数 , 放置一个 [CmdletBinding(PositionalBinding=$false, ...)] 属性高于 param(...)堵塞。
  • 由于这使您的函数成为高级函数,因此这也禁止传递任意附加参数( $args 不再适用且未填充)。
  • 顺便说一句:当您实现 cmdlet(作为二进制文件实现的命令,通常通过 C# 实现)时,这种行为是隐含的。
  • 有选择地支持位置参数 , 用 修饰单个参数声明[Parameter(Position=<n>, ...)] 属性(例如, [Parameter(Position=0)] [string] $Path )
  • 注意:是否以 0 开始编号或 1没关系,只要使用的数字反射(reflect)了所有位置参数中所需的排序; 0建议作为自文档约定,因为它是明确的。
  • 属性 [Parameter(Position=<n>)]是有选择地覆盖 [CmdletBinding(PositionalBinding=$false)] 的显式选择加入: 也就是说,后者禁用位置绑定(bind),除非单独的参数声明明确指出;事实上,后者是由前者隐含的,即使用一次 [Parameter(Position=<n>)]属性,您必须在所有其他要在位置上绑定(bind)的参数上使用它 .


  • [1] 请注意,PowerShell [Core] 7.0+ 原生支持三元条件: $sw ? 'trueValue' : 'falseValue'
    [2] 实际上, [switch]参数是 PowerShell 支持可选参数的唯一类型。见 this answer想要查询更多的信息。

    关于带有字符串数组的powershell函数开关参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60244612/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com