Powershell splatting:在散列 table 中传递 ErrorAction = Ignore

Powershell splatting: pass ErrorAction = Ignore in hash table

这是一个脚本,用于列出在命令行上传递的目录/文件——是否递归:

param( [switch] $r )
@gci_args = @{
  Recurse = $r
  ErrorAction = Ignore
}
$args | gci @gci_args 

现在这不起作用,因为 Ignore 被解释为文字。传递 ErrorAction 的规范方式是什么?

我看到 "Ignore" 和(在 PS7 中){ Ignore } 都作为值工作,但似乎都没有对我的用例产生影响(在 Linux,它会停止 PS5 而不管 ErrorAction,但根本不会打扰 PS7)。所以我什至不确定参数是否有任何影响。

我认为最好的方法是使用原生类型。

$ErrorActionPreference.GetType().FullName # System.Management.Automation.ActionPreference

所以,使用

$gci_args = @{   
  Recurse = $r
  ErrorAction = [System.Management.Automation.ActionPreference]::Ignore
}

because Ignore is interpreted as a literal

不,Ignore被解释为执行的命令,因为它在中被解析参数模式(命令调用,如shell),而不是表达式模式(如传统编程语言)——参见了解更多信息。

虽然使用 [System.Management.Automation.ActionPreference] enumeration value explicitly, as in 绝对是一种选择,但您可以利用 PowerShell 自动在 enum 值及其符号 字符串表示.

因此,您可以使用 string 'Ignore' 作为 [System.Management.Automation.ActionPreference]::Ignore 更方便的替代方法:[1]

$gci_args = @{
  # ... 
  ErrorAction = 'Ignore'
}

请注意,正是 quoting ('...') 向 PowerShell 发出信号 expression-mode 应该使用解析,即标记是 字符串文字 而不是命令。

另请注意,-ErrorAction 仅在 非终止 错误(然而,这是典型的错误)上运行 - 请参阅 了解更多信息。


至于发现允许的-ErrorAction值:

  • 概念性 about_CommonParameters 帮助主题涵盖了所有 公共参数 ,其中 -ErrorAction 是一个。

  • 许多常用参数都有相应的 偏好变量(接受相同的值),涵盖在 about_Preference_Variables 中,这使您可以 预设个常用参数

  • Interactively,您可以使用 tab-completion 查看允许的值(作为不带引号的符号名称,你只需要用引号引起来);例如:

    # Pressing the Tab key repeatedly where indicated 
    # cycles through the acceptable arguments.
    Get-ChildItem -ErrorAction <tab> 
    

[1] 请注意,如果上下文明确要求特定 enum 类型,则使用字符串 意味着放弃类型安全,例如在这种情况下。考虑到 PowerShell 是一种解释 语言,验证只会在运行时 发生。
但是,PowerShell 感知的 编辑器 (例如带有 PowerShell 扩展的 Visual Studio 代码)可能会在 设计时 [=93] 标记不正确的值=].然而,从版本 2020.6.0 开始, 并非 似乎是这种情况。不过幸运的是,tab-completion 和 IntelliSense 按预期工作,所以问题可能不会出现。
也就是说,如 zett42 points out, in the context of defining a hashtable entry for latter splatting the expected type is not (yet) known, so explicit use of [System.Management.Automation.ActionPreference] does have advantages: (a) IntelliSense in the editor can guide you, and (b) - assuming that Set-StrictMode -Version 2 or higher is in effect - an invalid value will we reported earlier at runtime, namely at the point of assignment, which makes troubleshooting easier. As of PowerShell 7.1, a caveat regarding Set-StrictMode -Version 2 or higher is that you will not be able to use the intrinsic (PowerShell-supplied) .Count property on objects that don't have it type-natively, due to the bug described in GitHub issue #2798.