gpt4 book ai didi

powershell - 在 PowerShell 中实现子命令模式

转载 作者:行者123 更新时间:2023-12-04 17:47:02 25 4
gpt4 key购买 nike

是否可以在 PowerShell 中实现子命令模式?就像是:

command [subcommand] [options] [files]

示例:Git、svn、Homebrew

一般架构是什么?将实际工作委托(delegate)给脚本 block 的单个函数?每个子命令都以自己的方式隔离 PS1由主脚本作为点源的文件? PowerShell 的各种元数据函数(例如 Get-Command )是否能够“检查”子命令?

最佳答案

我想到了这种模式,并找到了两种方法。我没有找到
实际应用在我的实践中,所以研究是相当学术的。但
下面的脚本工作正常。

实现此模式(以自己的方式)的现有工具是
scoop .

pattern 子命令实现了经典的命令行界面

app <command> [parameters]

此模式引入了单个脚本 app.ps1它提供命令
而不是在脚本库中提供多个脚本或函数,或者
模块。每个命令都是特殊子目录中的一个脚本,例如。/命令。

获取可用命令
app

调用命令
app c1 [parameters of Command\c1.ps1]

获取命令帮助
app c1 -?     # works with splatting approach
app c1 -help # works with dynamic parameters

脚本 app.ps1 可能包含命令使用的常用函数。

splat.ps1 (as such app.ps1) - 带有飞溅的图案

优点:
  • 最少的代码和开销。
  • 位置参数起作用。
  • -?按原样寻求帮助(简短帮助)。

  • 缺点:
  • PowerShell v3+,飞溅在 v2 中很有趣。


  • dynamic.ps1 (as such app.ps1) - 带有动态参数的模式

    优点:
  • PowerShell v2+。
  • TabExpansion 适用于参数。

  • 缺点:
  • 更多代码,更多运行时工作。
  • 仅命名参数。
  • 帮助为 -help .


  • 脚本

    splat.ps1
    #requires -Version 3

    param(
    $Command
    )

    if (!$Command) {
    foreach($_ in Get-ChildItem $PSScriptRoot\Command -Name) {
    [System.IO.Path]::GetFileNameWithoutExtension($_)
    }
    return
    }

    & "$PSScriptRoot\Command\$Command.ps1" @args

    动态.ps1
    param(
    [Parameter()]$Command,
    [switch]$Help
    )
    dynamicparam {
    ${private:*pn} = 'Verbose', 'Debug', 'ErrorAction', 'WarningAction', 'ErrorVariable', 'WarningVariable', 'OutVariable', 'OutBuffer', 'PipelineVariable'
    $PSScriptRoot = Split-Path $MyInvocation.MyCommand.Definition

    $Command = $PSBoundParameters['Command']
    if (!$Command) {return}

    $_ = Get-Command -Name "$PSScriptRoot\Command\$Command.ps1" -CommandType ExternalScript -ErrorAction 1
    if (!($_ = $_.Parameters) -or !$_.Count) {return}

    ${private:*r} = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary
    (${private:*a} = New-Object System.Collections.ObjectModel.Collection[Attribute]).Add((New-Object System.Management.Automation.ParameterAttribute))
    foreach($_ in $_.Values) {
    if (${*pn} -notcontains $_.Name) {
    ${*r}.Add($_.Name, (New-Object System.Management.Automation.RuntimeDefinedParameter $_.Name, $_.ParameterType, ${*a}))
    }
    }
    ${*r}
    }
    end {
    if (!$Command) {
    foreach($_ in Get-ChildItem $PSScriptRoot\Command -Name) {
    [System.IO.Path]::GetFileNameWithoutExtension($_)
    }
    return
    }

    if ($Help) {
    Get-Help "$PSScriptRoot\Command\$Command.ps1" -Full
    return
    }

    $null = $PSBoundParameters.Remove('Command')
    & "$PSScriptRoot\Command\$Command.ps1" @PSBoundParameters
    }

    关于powershell - 在 PowerShell 中实现子命令模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30792435/

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