脚本参数匹配

时间:2016-11-04 17:30:00

标签: powershell command-line-arguments

PowerShell在处理传递给脚本的参数时是否会进行某种最接近的匹配或自动完成?鉴于此代码......

[CmdletBinding()]
Param(
    [string][Alias("aS")] $applySet,
    [string][Alias("cS")] $conformSet,

    [string][Alias("sL")] $setList,
    [Parameter(ValueFromRemainingArguments = $true)][Object[]]$extraParameters = @()
)

Write-Host "s:  $set"
Write-Host "sL: $setList"
Write-Host "aS: $applySet"
Write-Host "cS: $conformSet"
Write-Host "X:  $extraParameters"

如果我在脚本快捷方式中使用 -junk" junk" ,我会按预期在$extraParameters中获取该信息。拼错的东西,比如 -aplySet ,也会显示为一个额外的参数。但是,使用 -set 实际上会填充$setList变量而不是$extraParameters,正如我所期望的那样。

在PowerShell 2.0和5.1中验证。有什么想法吗?

2 个答案:

答案 0 :(得分:3)

PowerShell允许使用参数名称的初始字符,只要它们是明确的。

答案 1 :(得分:3)

据我所知,它有点无证。

  • about_Parameters没有提及使用缩写参数。
  • about_Command_Syntax讨论使用参数而不是短版本。
  • Save-Help' d所有帮助和 grep sls&d;它可能是条款,看不到任何相关内容。
  • This blog post from 2006谈论它,因此自1.0版以来它一直在PowerShell中。
  

在PowerShell 1.0中,参数名称解​​析逻辑的一部分包括支持通过唯一标识参数的最短子字符串或与cmdlet的参数和别名列表进行比较来识别参数的别名。

并且在PowerShell开发人员Bruce Payette的书中提到了PowerShell In Action'第2章,P.39-40:

  

PowerShell解释器的所有部分都将其称为参数绑定器。参数绑定器是智能的 - 只要您指定足够的参数以便唯一地区分您的意思,它就不需要您指定参数的全名。

但那就是它,没有评论我能看到的设计选择或理由。正如@Mike Shepard所评论的那样,PowerShell作为交互式shell的双重角色(人们希望尽可能少地输入,并且正在编写一次性的一次性命令)和脚本语言(人们想要清晰,可读性) ,多个人在较长时间内的可维护性是产生一切的短形式/长形式的原因。

gci -r | sls (date)
Get-ChildItem -Recurse | Select-String -Pattern (Get-Date)
  • 别名
  • 位置参数绑定,不带参数名称
  • 参数名称缩写
  • 参数到对象属性自动绑定
  • 如果Get-被遗漏
  • ,则命令解析可以查找Get-个cmdlet

Fwiw,它似乎是System.Management.Automation/engine/MergedCommandParameterMetadat.cs的{​​{3}},PowerShell Slack上的某个人确定了,这实际上是参数匹配:

foreach (string parameterName in _bindableParameters.Keys)
{
// ---
    if (CultureInfo.InvariantCulture.CompareInfo.IsPrefix(parameterName, name, CompareOptions.IgnoreCase))
// ---
    {
        // If it is an exact match then only return the exact match
        // as the result

        if (tryExactMatching && String.Equals(parameterName, name, StringComparison.OrdinalIgnoreCase))
        {
            return _bindableParameters[parameterName];
        }
        else
        {
            matchingParameters.Add(_bindableParameters[parameterName]);
        }
    }
}