【问题标题】:Powershell:option with multiple argumentsPowershell:具有多个参数的选项
【发布时间】:2021-06-27 10:09:17
【问题描述】:

我想做这样的事情:

param (
    [String[]]${firstArray},
    [string[]]${secondArray}
    )
Write-Host "firstArray: $firstArray"
Write-Host "args: $args"
Write-Host "secondArray: $secondArray"

但我希望它在没有“,”的情况下调用 实际上结果是:

.\test.ps1 -firstArray args1 args2 -secondArray args3 args4
firstArray: args1
args: args2 args4
secondArray: args3 

但我想要一种方法来做到这一点:

.\test.ps1 -firstArray args1 args2 -secondArray args3 args4
firstArray: args1 args2
args: 
secondArray: args3 args4

我知道可以用“,”这样的:

.\test.ps1 -firstArray args1, args2 -secondArray args3, args4
firstArray: args1 args2
args: 
secondArray: args3 args4

但我想知道没有它是否可能。

【问题讨论】:

    标签: powershell syntax parameter-passing


    【解决方案1】:

    你可以用ValueFromRemainingArguments装饰一个参数:

    function f {
      param(
        [Parameter(ValueFromRemainingArguments)]
        [String[]]${firstArray},
        [string[]]${secondArray}
      )
    
      Write-Host "firstArray: $firstArray"
      Write-Host "args: $args"
      Write-Host "secondArray: $secondArray"
    }
    
    PS ~> f -secondArray 1,2,3 a b c d
    firstArray: a b c d
    args:
    secondArray: 1 2 3
    

    【讨论】:

    • 谢谢,但我希望每个参数都可以,我会编辑我的问题。
    • @NemuraNai 恐怕这是不可能的(让 PowerShell 的内置参数绑定器为你做这件事) - 你最好的选择是在函数体内手动检查 $MyInvocation 并重新分配参数 -不是我推荐的 :-) 你试图唤起这种非常具体的行为的动机是什么?你想解决什么问题?
    • 这是一个练习,应该使用:f -firstArray arg1 arg2 或使用:f -secondArray arg1 arg2 调用,所以我意识到使用 switch 更相关,因为 firstArray 和 secondArray 不应该一起调用。跨度>
    【解决方案2】:

    Mathias' helpful answer 向您展示如何使用ValueFromRemainingArguments 参数属性来声明一个收集所有参数的参数:

    • 没有绑定到任何其他参数,
    • 表示它们只能是位置的,即未命名,意思是:前面有参数name,如-firstArray

    换句话说:如果你使用ValueFromRemainingArguments 来声明$firstArray (-firstArray),那么只有两种互斥的方式来传递multiple(一个数组of) 的论据

    • 通过命名目标参数,然后需要,来分隔(子)参数:

      • .\test.ps1 -firstArray args1, args2 -secondArray args3, args4
    • 如果您希望能够用空格分隔参数必须命名目标参数 ,即你必须传递参数位置

      • .\test.ps1 args1 args2 -secondArray args3, args4

    PowerShell 不允许您混合使用这两种方法;也就是说,你想要的语法:

    .\test.ps1 -firstArray args1 args2 ...不起作用


    如果可能的话,解决这个问题将是一项非常重要的工作,但更重要的是,与 PowerShell 的参数语法作斗争以叠加自定义逻辑是概念上有问题的,尤其是因为它只能工作你的脚本/函数,一般不会。

    【讨论】:

      【解决方案3】:

      当您不声明任何函数参数(即不使用param 块)时,这是可能的。然后自动变量$args 将包含所有参数标记,您可以应用自己的解释逻辑。

      Function Fun {
          [String[]] $firstArray  = @()
          [String[]] $secondArray = @()
          [ref] $arrayToAppend = $null
      
          # For each argument token
          foreach( $token in $args ) {
              if( $token -eq '-firstArray' ) {
                  # Enter 1st array parsing mode
                  $arrayToAppend = [ref] $firstArray
              }
              elseif( $token -eq '-secondArray' ) {
                  # Enter 2nd array parsing mode
                  $arrayToAppend = [ref] $secondArray
              }
              elseif( $null -ne $arrayToAppend ) {
                  # Append to either 1st or 2nd array
                  $arrayToAppend.Value += $token
              }
          }
      
          "firstArray : $($firstArray -join ', ')"
          "secondArray: $($secondArray -join ', ')"
      }
      
      Fun -firstArray 1 2 -secondArray 3 4
      

      输出:

      firstArray : 1, 2
      secondArray: 3, 4
      

      说明:

      在函数代码中,我使用了reference variable$arrayToAppend,它将引用第一个或第二个数组。因此,通过附加到该变量的 Value 成员,我们实际上将附加到两个数组之一。

      注意事项:

      我同意mklement0 的观点,即这在概念上是有问题的。如果其他开发人员看到调用代码,可能会使他们感到困惑,因为它不同于用于传递数组字面量的常规 PowerShell 代码。

      话虽如此,这样的代码可能有有效的用途,例如。 G。为了向后兼容现有的工具链。

      【讨论】:

      • 感谢更新。不想说得太细,但为了未来的读者,我不认为不要做这个部分应该是事后考虑。 OP 本质上是问:PowerShell 不是设计用来做什么的?你对那个给出了一个很好的答案,但在事情的宏伟计划中,不要做这个方面更重要。
      猜你喜欢
      • 1970-01-01
      • 2022-11-26
      • 1970-01-01
      • 2023-04-07
      • 2011-08-12
      • 2018-07-21
      • 2022-10-15
      • 1970-01-01
      • 2013-01-06
      相关资源
      最近更新 更多