gpt4 book ai didi

powershell - 有没有办法以仅在将参数传递给别名的情况下运行的方式为cmdlet创建别名?

转载 作者:行者123 更新时间:2023-12-02 22:36:01 25 4
gpt4 key购买 nike

我正在尝试以某种方式发送create an alias cmdlet的Get-Command(名为,即),如果我不发送任何参数,它就不会运行(因为如果没有参数运行,它将输出所有可用的命令)。

我知道可以使用函数来完成此操作,但是我想保留制表符完成功能,而不必编写要放入我的$PROFILE的较大函数。

简而言之,我只希望别名在传递参数时起作用。

最佳答案

您不能使用别名来完成此操作,因为 PowerShell别名只能引用另一个命令名或路径,因此既不能包含参数也不能包含自定义逻辑
因此,您确实需要一个函数,但它可能是一个简短的:

function which { if ($args.count) { Get-Command @args } else { Throw "Missing command name." } }
请注意,虽然传递 -?来显示 Get-Command的帮助确实有效,但参数的制表符补全却无效。
为了获得制表符的完成,还需要编写一个包装器(代理)函数,或者至少复制Get-Command的参数声明,这确实会使函数定义变得可调整。
如果只考虑 $PROFILE文件本身的大小,则可以编写一个代理脚本 which.ps1,也可以仅使用 which调用它,假设您将其放置在 $env:Path [1]中列出的目录之一中;请参阅下一节。

定义包装器(代理)脚本或函数:
Defining a wrapper (proxy) function or script是一项艰巨的任务,但是允许您实现一个强大的包装器,该包装器支持制表符补全,甚至可以转发到原始命令的帮助。
笔记:
  • 错误警报:正如zett42所指出的那样,从PowerShell [Core] 7.1开始,如果目标命令是(高级)函数或脚本,则 System.Management.Automation.ProxyCommand.Create 忽略了包含动态参数。但是,编译的cmdlet不会受到影响;解决方法,请参见GitHub issue #4792this answer
  • 为简单起见,以下代码创建了一个包装脚本which.ps1,并将其保存在当前目录中。如前所述,如果将其放置在$env:PATH列出的目录之一中,则可以像which一样调用它。
  • 下面的代码可以轻松地改编为创建包装函数:只需获取下面$wrapperCmdSource变量的内容,并将其包含在function which { ... }中。
  • 从PowerShell Core 7.0.0-preview.5开始,自动生成的代码存在一些问题,可能会或不会影响您;他们将被固定在某个时候;要了解更多信息并了解如何手动更正它们,请参阅this GitHub issue
  • # Create the wrapper scaffolding as source code (outputs a single [string])
    $wrapperCmdSource =
    [System.Management.Automation.ProxyCommand]::Create((Get-Command Get-Command))

    # Write the auto-generated source code to a script file
    $wrapperCmdSource > which.ps1
    笔记:
  • 即使 System.Management.Automation.ProxyCommand.Create 需要 System.Management.Automation.CommandMetadata 实例来标识目标命令,但System.Management.Automation.CommandInfo输出的 Get-Command 实例仍可以按原样使用。
  • 关于基于注释的帮助:默认情况下,代理功能仅转发至原始cmdlet的帮助。但是,您可以选择将字符串用作第二个参数,以用作基于注释的帮助。
  • 通过结合使用[System.Management.Automation.ProxyCommand]::GetHelpComments()Get-Help的输出,您可以从原始命令帮助的副本开始并进行修改:[System.Management.Automation.ProxyCommand]::GetHelpComments((Get-Help Get-Command))


  • 现在,您将拥有一个功能完整的 which.ps1包装器脚本,该脚本的行为类似于Get-Command本身
    您可以按以下方式调用它:
    ./which  # Same as: Get-Command; tab completion of parameters supported.
    ./which -? # Shows Get-Command's help.
    现在,您可以编辑脚本文件以执行所需的自定义。
    注意:自动生成的源代码包含很多样板代码;但是,通常只有一两个地方需要调整以实现自定义功能。
    具体来说,将以下命令作为第一个语句放入 begin { ... }块中:
    if (-not $MyInvocation.ExpectingInput -and -not ($Name -or $CommandType -or $Module -or $FullyQualifiedModule)) {
    Throw "Missing command name or filter."
    }
    如果调用者未提供通过直接参数或通过管道定向特定命令或命令组的某种方式,这将导致脚本引发错误。
    如果现在调用不带参数的修改后的脚本,则应该看到所需的错误:
    PS> ./which.ps1
    Missing command name or filter.
    ...

    其他 常见的自定义类型是:
  • 只需删除参数声明,即可从包装器中删除参数。
  • 通过修改begin块中的以下行,将其他参数添加到包装命令的调用中:
      # Add parameters, as needed.
    $scriptCmd = { & $wrappedCmd @PSBoundParameters }
  • 通过自定义process块并将$_替换为以下行中的预处理输入,在将其传递给包装的命令之前对其进行预处理:
      # Replace $_ with a preprocessed version of it, as needed.
    $steppablePipeline.Process($_)

  • [1]对Linux用户的警告:由于Linux文件系统区分大小写,因此脚本调用不区分大小写,因此命令在PowerShell中的正常工作方式。例如,如果您的脚本文件名为 Get-Foo.ps1,则仅 Get-Foo(使用完全相同的大小写)将起作用,例如 get-foo也不起作用。

    关于powershell - 有没有办法以仅在将参数传递给别名的情况下运行的方式为cmdlet创建别名?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55539278/

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