在 Powershell 中,Write-Host 会调用管道对象上的任何方法

In Powershell does Write-Host call any method on piped object

Write-Host 对管道 data/objects 做了什么操作?

在我的例子中,如果我执行 $xmlContent,它将输出 table 个对象,如果我执行 $xmlContent | Write-Host,它将输出实际的 XML。当我执行 $xmlContent.ToString() 时,它与 Write-Host 生成的输出不同。于是就有了上面的问题。

应该是因为 ToString() 是 from the underlying PSObject,给你一个对象的字符串表示。 因此,如果您键入对象,结果会发生变化。 然后 ToString() 将取决于您输入的内容。 Write-Host 将调用 ToString()。

我尝试了 3 种场景来观察差异: Last scenario is from Shay Levy's post.

$untyped = Get-Content 'some.xml'
$untyped.ToString()
$pureDoc | Write-Host 

[xml]$typed =  Get-Content 'some.xml'
$typed.ToString()
$typed | Write-Host 

$pso = new-object psobject -property @{ name = 'bob'; job = 'janitor' }
$pso | add-member scriptmethod ToString { 'he is a {0}, he is' -f $this.job } -force 
$pso.ToString()
$pso | Write-Host

输出为:

System.Object[]
[XML omitted for brevity]
#document
#document
he is a janitor, he is
he is a janitor, he is

你看 Write-Host 是如何实现的 returns 什么都变成了 ToString() 的实现?

Write-Host 做了一些通常违反直觉的事情或者不是最好的做事方式,所以我不鼓励你使用它。相反,请查看 Write-VerboseWrite-Output(或者尝试 Get-Help Write-* 以查看所有可能性)。

输入:

Write-Host 以意想不到的方式更改输入。当输出 stringint 或其他熟悉的类型时,它会输出该输入的内容。但是,正如我确定您已经看到并感到困惑的那样,有些类型 Write-Host 不会输出其内容,相反,它只会输出输入的 类型 。这在大多数情况下毫无用处。

输出:

Write-Host 输出的格式与自己写入输入或在函数中写入 return 的格式相同。这三个对于字符串类型可以等价使用,例如:

$str

Write-Host $str

return $str #in context of a function

再次注意,它们对于 string 类型和其他一些类型是等价的,但是 Write-Host 可能会以奇怪的方式对其他类型的输入进行操作。

一般来说,不鼓励使用Write-Host。要 debug/output 进行安慰,请使用 Write-Verbose。要输出到管道或从函数中输出,请自行编写变量。这将输出我们在 powershell 中习惯使用的漂亮的字典样式格式:

PS C:\Windows\system32> $dict

Name                           Value
----                           -----
key                            value
{test, test2}                  1

相比于:

PS C:\Windows\system32> write-host $dict
System.Collections.DictionaryEntry System.Collections.DictionaryEntry