powershell - 如何将一个PowerShell函数的 'argument-line'传递给另一个函数?

标签 powershell metaprogramming splat

我正在尝试编写一些 PowerShell 函数来执行一些操作,然后透明地调用现有的内置函数。我想原封不动地传递所有的论点。我不想知道论点的任何细节。

我厌倦了使用“splat”与 @args 来完成此操作,但这并没有像我预期的那样工作。

在下面的示例中,我编写了一个名为 myls 的玩具函数,它应该打印 hello!,然后调用相同的内置函数 Get-ChildItem,内置别名 ls 调用时参数行的其余部分保持不变。到目前为止我所拥有的效果很好:

function myls
{
  Write-Output "hello!"
# $MyInvocation | Format-List          # <-- uncomment this line for debug info
  Invoke-Expression ("Get-ChildItem " + $MyInvocation.UnboundArguments -join " ")
}

myls 的正确版本应该能够处理不带参数、带一个参数、带命名参数、从包含多个分号分隔命令的行以及在参数包括包含空格的字符串变量。基本上,它应该是 ls 的直接替代品。

下面的测试比较 myls 和内置 ls:

[注意:输出被省略和/或压缩以节省空间]

PS> md C:\p\d\x, C:\p\d\y, C:\p\d\"jay z"
PS> cd C:\p\d
PS> ls                                 # no args
PS> myls                               # pass
PS> cd ..
PS> ls d                               # one arg
PS> myls d                             # pass
PS> $a="A"; $z="Z"; $y="y"; $jz="jay z"
PS> $a; ls d; $z                       # multiple statements
PS> $a; myls d; $z                     # pass
PS> $a; ls d -Exclude x; $z            # named args
PS> $a; myls d -Exclude x; $z          # pass
PS> $a; ls d -Exclude $y; $z           # variables in arg-line
PS> $a; myls d -Exclude $y; $z         # pass
PS> $a; ls d -Exclude $jz; $z          # variables containing spaces in arg-line
PS> $a; myls d -Exclude $jz; $z        # FAIL!

有没有办法可以重写 myls 来获得我想要的行为?

简短回答:是的,这是可能的。坏消息:它需要知道参数详细信息以及有关希望调用的函数的其他元数据的代码。好消息:不需要自己编写这些。该元数据可以通过编程方式获得,并且存在可用的模块,可用于自动生成骨架代理代码(请参阅下面@Jaykul的答案)。我选择使用the module named "MetaProgramming" 。导入后,生成嵌入式 myls 脚本非常简单:

New-ProxyCommand ls > .\myls.ps1

然后就可以开始自定义新生成的 myls.ps1 脚本,如下所示:

  ...
  begin
  {
    Write-Output "hello!"              # <-- add this line
    try {
      $outBuffer = $null
  ...

瞧!这个新版本通过了所有测试。

最佳答案

如果你想要 ls 的直接包装器,你应该写一个 proper Proxy Command 。 PoshCode.org 上有几个版本的生成器,包括 the one from Lee Holmes' PowerShell Cookbook ,

但是现在内置了代理命令生成器,因此您可以编写:

$CommandName = "Get-ChildItem"
$Command = Get-Command $CommandName
[System.Management.Automation.ProxyCommand]::Create($Command)

关于powershell - 如何将一个PowerShell函数的 'argument-line'传递给另一个函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4702406/

相关文章:

powershell - 将 7-zip 参数作为变量插入

azure - 使用power-shell在azure中注册具有多个订阅的多个资源提供者

javascript - 如何从子类的实例访问 typescript 中的静态属性?

dictionary - Julia-Lang 元编程 : turn expression into function with expression-dependent arguments

c++ - 使用 constexpr 在编译时初始化指向成员函数的指针数组

ruby - (unary) * 运算符在此 Ruby 代码中的作用是什么?

CoffeeScript:在函数调用中扩展数组

ruby - `nil` 上的双响

powershell - SharePoint CSOM PowerShell 不返回 Web.Folders 属性

azure - 通过 powershell 创建日志警报规则并将多个操作组附加到该规则