【问题标题】:PowerShell how to use $MyInvocation for recursionPowerShell 如何使用 $MyInvocation 进行递归
【发布时间】:2014-11-13 14:51:18
【问题描述】:

我正在尝试使用 PowerShell 实现一些递归函数。这是基本功能:

function MyRecursiveFunction {
    param(
        [parameter(Mandatory=$true,ValueFromPipeline=$true)]
        $input
    )

    if ($input -is [System.Array] -And $input.Length -eq 1) {
        $input = $input[0]
    }

    if ($input -is [System.Array]) {
        ForEach ($i in $input) {
            $i | ##### HOW DO I USE $MyInvocation HERE TO CALL MyRecursiveFunction??? #####
        }
        return
    }

    # Do something with the single object...
}

我查看过 Invoke-Expression 和 Invoke-Item 但无法正确使用语法。比如我试过

$i | Invoke-Expression $MyInvocation.MyCommand.Name

我猜如果你知道正确的语法,有一个简单的方法可以做到这一点:-)

【问题讨论】:

  • 我建议将$input 更改为另一个变量名。 $input 是 powershell 脚本中的保留和自动填充变量:stackoverflow.com/a/885651/520612
  • @CB。点了,谢谢。我实际上希望用我的变量隐藏自动变量,但回想起来,也许这不是一个好主意。

标签: powershell


【解决方案1】:

只需调用函数:

$i | MyRecursiveFunction

要在不知道函数名称的情况下调用它,您应该能够使用 $myInvocation.InvocationName 来调用它:

Invoke-Expression "$i | $($myInvocation.InvocationName)"

【讨论】:

  • 这是一个完全有效的解决方案。但是,我要实现的功能不止一个。每次,我剪切并粘贴样板代码来处理将数组作为单个对象输入,我必须记住将其中一行更改为新的函数名称。当我忘记更改它时,这已经给我带来了几次问题。我不是 PS 专家,一般来说可能有更好的方法,但现在,我希望使用 $MyInvocation 来使样板文件更通用。
  • 仅供参考,一般来说,如果您重复使用相同的样板代码,您可能可以进一步概括您的代码。
【解决方案2】:

有点老问题,但由于没有令人满意的答案,我也有同样的问题,这是我的经验。

如果名称更改或函数超出范围,则按名称调用函数将中断。管理起来也不是很好,因为更改函数名称需要编辑所有递归调用,并且可能会中断使用前缀选项导入的模块。

# A simple recursive countdown function
function countdown {
    param([int]$count)
    $count
    if ($count -gt 0) { countdown ($count - 1) }
}

# And a way to break it
$foo = ${function:countdown}
function countdown { 'failed' }
& $foo 5

$MyInvocation.InvocationName 使用起来稍微好一些,但在上面的示例中仍然会中断(尽管出于不同的原因)。


最好的方法似乎是调用函数的脚本块$MyInvocation.MyCommand.ScriptBlock。这样,无论函数名称/范围如何,它仍然可以工作。

function countdown {
    param([int]$count)
    $count
    if ($count -gt 0) { & $MyInvocation.MyCommand.ScriptBlock ($count - 1) }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-04
    • 2018-11-02
    • 2015-02-02
    • 2012-07-08
    相关资源
    最近更新 更多