【问题标题】:Script Argument matching脚本参数匹配
【发布时间】:2017-03-18 15:18:54
【问题描述】:

在处理传递给脚本的参数时,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 中验证。有什么想法吗?

【问题讨论】:

    标签: powershell command-line-arguments


    【解决方案1】:

    据我所知,这有点无证。

    • about_Parameters 没有提到使用缩写参数。
    • about_Command_Syntax 谈论使用参数,但不是短版本。
    • Save-Help'd 提供了所有帮助,grep 为可能的术语提供了帮助,但看不到任何相关内容。
    • This blog post from 2006 谈论它,所以它从 PowerShell 1.0 版本开始就存在

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

    PowerShell 开发人员 Bruce Payette 的书“PowerShell In Action”第 2 章 P.39-40 中提到了这一点:

    计算所有这些的 PowerShell 解释器称为参数绑定器。参数绑定器很智能 - 它不需要您指定参数的全名,只要您指定的足够多,以便它能够唯一区分您的意思。

    仅此而已,我无法对设计选择或理由发表评论。推测,正如@Mike Shepard cmets,PowerShell 的双重角色是一个交互式外壳(人们希望尽可能少地输入,并且正在编写一次性的一次性命令)和脚本语言(人们希望通过多种方式获得清晰、可读性和可维护性)人们在更长的时间里)是产生所有东西的短形式/长形式版本的原因。

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

    Fwiw,它似乎是 System.Management.Automation/engine/MergedCommandParameterMetadat.cs 中的 this line in the source code,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]);
            }
        }
    }
    

    【讨论】:

    • 伟大的侦探。给哲学起个名字:弹性语法:“PowerShell 支持弹性语法——在命令行上简洁,在脚本中完成。” “之前我们说过,您只需要足够的参数名称即可将其与其他命令参数区分开来。”来自即将出版的“PowerShell in Action”第三版(第一章免费提供)-manning.com/books/windows-powershell-in-action-third-edition
    【解决方案2】:

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

    【讨论】:

    • 嗯,我“猜”是有道理的。至少在脚本语言中。有点希望它可以被关闭,就像我希望流水线输出一样。至少使用命令行参数。但现在我想我需要记录人们的行为,并停止尝试捕捉某些对 PS 来说确实不是错误的错误。
    • 在命令行中这是一种有用的行为(输入速度更快),但脚本中的最佳实践是将所有内容都拼写出来。
    • 没错。我想抓住每一个“不恰当的”使用。但这似乎规避了这一点,因为我无法正确地将 -set 捕获为错误,因为 PowerShell 自动假定 -setlist 是指的。我们都知道假设。 ;)
    猜你喜欢
    • 1970-01-01
    • 2017-11-25
    • 2010-09-19
    • 1970-01-01
    • 1970-01-01
    • 2018-08-23
    • 1970-01-01
    • 2017-05-02
    • 2018-11-05
    相关资源
    最近更新 更多