在Powershell foreach-object -parallel中,写信息似乎不起作用

问题描述

我是PowerShell的新手,只是学习它。我有一些C#的经验。我正在尝试使用foreach-object -Parallel选项,但无法使所有Write- *函数正常工作。

function writeTest {
        1..1 | ForEach-Object -Parallel {
            Write-Host "host"
            Write-Output "Output"
            Write-information "information" -informationAction Continue
            Write-Verbose "verbose"
            Write-Warning "Warning"
            Write-Error "error"       
        }
}

函数调用方式为:writeTest -verbose

输出

host
Output
WARNING: Warning
Write-Error: error

我的问题是为什么写详细信息和写信息不显示任何内容

请原谅任何无知。

解决方法

您在ForEach-Object -Parallel / Start-ThreadJob中看到了一个 bug ,至少出现在PowerShell Core 7.0中:

应该显示您的Write-Information输出 ,因为您已经使用-InformationAction Continue将其打开;虽然您的Write-Verbose输出未显示是预期的,因为您没有使用-Verbose将其打开,但由于该错误,它也不会显示是否使用了-Verbose

请参见GitHub issue #13816

解决方法是要设置首选项变量 $InformationPreference,以便在调用{之前打开信息流{1}}(请参见下文)。

另外,您的代码存在概念上的问题

  • 您正在将ForEach-Object -Parallel通用参数传递给-Verbose函数,但是该函数并未声明为 advanced 函数(它需要一个{ write-Test块上方的{1}}属性和/或至少一个具有[CmdletBinding()]属性的参数-请参见about_Functions_Advanced),因此该参数无效。

  • 即使它确实生效,这也意味着PowerShell将其转换为具有值param(...)的函数局部[Parameter(...)]变量,$VerbosePreference块也不会看到该变量,因为需要'Continue'范围来引用调用者范围中的变量值;参见this answer

将它们放在一起。

ForEach-Object -Parallel

请注意传递给$using:开关的 expression ,必要时用function Write-Test { # Mark the function as an advanced one,so that it accepts # common parameters such as -Verbose [CmdletBinding()] param() # WORKAROUND: Turn the information stream on # via its *preference variable* AS WELL: $InformationPreference = 'Continue' 1..1 | ForEach-Object -Parallel { Write-Host "host" Write-Output "Output" Write-Information "information" -InformationAction Continue Write-Verbose "verbose" -Verbose:($using:VerbosePreference -eq 'Continue') Write-Warning "Warning" Write-Error "error" } } Write-Test -Verbose --Verbose与开关名称分隔开-实际上,它仅打开冗长如果函数主线程(:)中的-Verbose:($using:VerbosePreference -eq 'Continue')值设置为$VerbosePreference,则输出,当$using:从外部传递给高级函数时,会发生这种情况(如果由于PowerShell的动态作用域,在调用者的范围内将'Continue'设置为-Verbose,也会发生这种情况;请参阅this answer)。


有关PowerShell输出流的常规信息

  • $VerbosePreference'Continue'都默认为沉默Write-Verbose也是如此。

  • 您可以通过以下两种方式之一显示其输出:

    • 每个命令,通过公用参数:将Write-Information添加到Write-Debug调用中,将-Verbose添加到Write-Verbose调用中(完成操作)。

    • 范围内,通过首选项变量:设置InformationAction ContinueWrite-Information-但是 caveat 是没有一个函数有效在(其他)模块中的 或在其他线程或进程中运行的代码都默认情况下会看到以下变量:

      • 在模块情况下,您必须显式使用公共参数,或者在 global 范围内设置首选项变量,这是不可取的。问题在GitHub issue #4568中进行了讨论。
      • 在其他线程/进程情况下,需要$VerbosePreference = 'Continue'范围,如上所示。

请参见about_Redirectionabout_CommonParametersabout_Preference_Variables

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...