PowerShell传递函数接收到的所有参数,并处理带空格的参数

PowerShell pass all parameters received in function, and handle parameters with spaces

我是 PowerShell 的新手。 在Msys2(或Lnux)中,我定义了一个函数npp

npp ()
{
    ${NPP_PATH} "$@"
}

这样,如果我从命令提示符 npp 调用,它会启动 Notepad++(如 ${NPP_PATH} 中所定义)。 如果我调用 npp "mydir/stage 1/a.txt" 它会打开该文件进行编辑。 一般来说,它允许:

  1. 任意数量的参数。
  2. 包含空格的参数(如果适当转义)。

PowerShell 中的等价物是什么?

我想在 PS 中我也应该寻找一个函数来获得类似的行为。 到目前为止,我可以接收未定义数量的参数,并在 foreach 循环中使用它们,请参见下面的代码。 但是我找不到简单的 "$@" 的等价物来传递接收到的所有参数。 此外,如果我在其中一个参数中使用引号,它们将被删除,因此包括空格在内的文件路径可能会出现问题。

function multi_params {
    param(
        [Parameter(
            ValueFromRemainingArguments=$true
        )][string[]]
        $listArgs
    )
    $count = 0
    foreach($listArg in $listArgs) {
        '$listArgs[{0}]: {1}' -f $count, $listArg
        $count++
    }
}

假设 NPP_PATH 是一个 environment 变量,等效的 PowerShell 函数是:

function npp {
  & $env:NPP_PATH $args
}

如果 NPP_PATH 是常规 PowerShell 变量的名称,请使用 & $NPP_PATH $args

&call operator,它是 syntactic 原因所必需的,只要你想调用一个命令,其 name/path 在引用 and/or 通过 变量.

simple functions (as opposed to advanced functions) such as the above (use of neither [CmdletBinding()] nor [Parameter()] attributes), you can use the automatic $args variable 中将任何参数传递给另一个命令。

  • 如果目标命令不是外部程序,比如这里,而是PowerShell命令,使用形式 @args 以确保所有参数 - 包括以其 参数名称 开头的参数 - 正确传递 - 参见 about_Splatting.
    请注意,形式 @args 也适用于外部程序,其中 通常 等同于 $args (唯一的区别是只有 @args 识别和删除 --%,停止解析标记)

  • 请注意,使用 嵌入的 " 字符传递参数。从 PowerShell v7.0 开始, 外部程序 的空参数 仍然损坏 - 请参阅 .


简单高级函数(脚本)中传递参数:

  • 仅在简单函数中,$args包含所有未绑定到[=的参数99=]在调用时声明 个参数,如果有的话。

    • 如果您的简单函数没有声明任何参数,如上例所示,$args 包含调用时传递的 所有 个参数。

    • 如果您的简单函数 确实 声明参数(通常通过 param(...)),$args 仅包含那些 未绑定到声明参数的参数;简而言之:它收集您的函数未为其声明参数的所有参数。

    • 因此,$args 是一种简单的机制,用于收集未声明或事先已知的参数,或者在函数本身中使用——特别是在声明参数不值得的情况下- 或者将这些参数传递给另一个命令。

    • 要将包含 named 参数(例如,-Path foo 而不仅仅是 foo)的参数传递给另一个 PowerShell 命令,需要 splatting,即 @args.

      形式
      • 请注意,虽然 $args 在技术上是一个常规的 PowerShell 数组 ([object[]]),但它也具有支持传递命名参数的内置魔法; 自定义数组可以用于此,hash-table形式然后需要飞溅 - 请参阅 about_Splatting
  • 高级函数中,$args不是 可用,因为 根据定义,高级函数只接受已声明参数的参数

    • 要接受额外的 positional-only 参数,您必须定义一个包罗万象的 ValueFromRemainingArguments 参数,如问题所示,默认情况下,将此类参数收集在类似数组的 [1] 数据结构中。

    • 要同时支持named 传递参数,您有两个基本选项:

      • 如果您知道一组潜在的传递参数,将它们声明为您自己的函数的一部分 .

        • 然后您可以使用 $PSBoundParameters 字典(散列 table)的 splatting - 见下文 - 传递命名参数,可能是在从字典中删除用于您的函数本身的参数之后。
      • 在为现有命令编写代理(包装器)函数时使用此技术; PowerShell SDK 允许您 脚手架 基于现有命令的代理函数,从而使复制传递参数更容易 - 请参阅 .

    • 否则,只有一个次优解决方案,您可以模拟 PowerShell 自己的参数解析,将位置参数解析为 parameter-name/value 对 - 请参阅 .


automatic $PSBoundParameters variable 是一个在 简单和高级功能中可用的字典:

  • $PSBoundParameters 仅当您的函数声明了参数时才适用,并且 仅包含那些 在声明的参数 中的条目参数实际上是在调用时绑定(传递)的;字典键是参数名称,尽管没有初始 -.
    请注意,受默认值约束的参数不包括 - 有关讨论,请参阅this GitHub issue
    再次注意,在 advanced 函数中,如果为其声明了参数,则只能传递给定参数,因此根据定义,给定调用中传递的任何参数都反映在 $PSBoundParameters 中.

  • 因为它是一个字典(散列table),它可以与散列-table基于splatting-@PSBoundParameters一起使用来传递命名参数到其他 PowerShell 命令,因为它是 mutable,您可以选择 addingremoving 命名参数(例如用于函数 本身 的参数)。


[1]那个类型是[System.Collections.Generic.List[object]];但是,您可以明确指定集合类型,例如 [object[]] 以获得常规 PowerShell 数组。