“Write-Host”,“Write-Output”或“[console] :: WriteLine”之间有什么区别?

时间:2012-01-06 09:02:38

标签: powershell

有许多不同的输出消息的方法。通过Write-HostWrite-Output[console]::WriteLine输出内容之间的有效区别是什么?

我还注意到,如果我使用:

write-host "count=" + $count

+包含在输出中。为什么?在写出表达式之前,是否应该对表达式进行求值以产生单个连接字符串?

6 个答案:

答案 0 :(得分:250)

如果要在管道中发送数据,则应使用

Write-Output,但不一定要在屏幕上显示数据。如果没有其他任何东西首先使用它,管道最终会将其写入out-default

当你想做相反的事情时,应该使用

Write-Host

[console]::WriteLine基本上是Write-Host在幕后所做的事情。

运行此演示代码并检查结果。

function Test-Output {
    Write-Output "Hello World"
}

function Test-Output2 {
    Write-Host "Hello World" -foreground Green
}

function Receive-Output {
    process { Write-Host $_ -foreground Yellow }
}

#Output piped to another function, not displayed in first.
Test-Output | Receive-Output

#Output not piped to 2nd function, only displayed in first.
Test-Output2 | Receive-Output 

#Pipeline sends to Out-Default at the end.
Test-Output 

您需要将连接操作括在括号中,以便PowerShell在标记Write-Host的参数列表之前处理连接。

write-host ("count=" + $count)

BTW - 观看Jeffrey Snover的这个video,解释管道是如何工作的。回到我开始学习PowerShell时,我发现这是管道工作原理的最有用的解释。

答案 1 :(得分:28)

除了安迪所提到的,还有另一个可能很重要的区别 - 写主机直接写入主机并且不返回任何内容,这意味着您不能将输出重定向到例如文件。

---- script a.ps1 ----
write-host "hello"

现在在PowerShell中运行:

PS> .\a.ps1 > someFile.txt
hello
PS> type someFile.txt
PS>

如图所示,您无法将它们重定向到文件中。对于不小心的人来说,这可能会令人惊讶。

但是如果切换到使用写输出,您将获得按预期重定向。

答案 2 :(得分:15)

这是完成写输出等效的另一种方法。只需将您的字符串放在引号中:

"count=$count"

通过运行此实验,您可以确保其与Write-Output的工作方式相同:

"blah blah" > out.txt

Write-Output "blah blah" > out.txt

Write-Host "blah blah" > out.txt

前两个会输出“blah blah”到out.txt,但第三个不输出。

“help Write-Output”给出了这种行为的提示:

  

此cmdlet通常用于脚本中以显示字符串和其他字符串   控制台上的对象。但是,因为默认行为是   显示管道末端的对象,通常不是   必须使用cmdlet。

在这种情况下,字符串本身“count = $ count”是管道末尾的对象,并显示。

答案 3 :(得分:3)

从我的测试写输出和[控制台] :: WriteLine()执行比写主机好得多。

根据您需要写出多少文字,这可能很重要。

下面如果5个测试的结果分别用于Write-Host,Write-Output和[Console] :: WriteLine()。

在我有限的经验中,我发现在处理任何类型的真实世界数据时,我需要放弃cmdlet并直接使用较低级别的命令来从我的脚本中获得任何不错的性能。

measure-command {$count = 0; while ($count -lt 1000) { Write-Host "hello"; $count++ }}

1312ms
1651ms
1909ms
1685ms
1788ms


measure-command { $count = 0; while ($count -lt 1000) { Write-Output "hello"; $count++ }}

97ms
105ms
94ms
105ms
98ms


measure-command { $count = 0; while ($count -lt 1000) { [console]::WriteLine("hello"); $count++ }}

158ms
105ms
124ms
99ms
95ms

答案 4 :(得分:1)

对于Write-Host的使用,PSScriptAnalyzer产生以下诊断:

  

避免使用Write-Host,因为它可能无法在所有主机上运行,​​在没有主机时也无法运行,并且(PS 5.0之前的版本)不能被抑制,捕获或重定向。而是使用Write-OutputWrite-VerboseWrite-Information

有关更多信息,请参见该规则后面的documentation。后代摘录:

  

强烈建议不要使用Write-Host,除非使用带有Show动词的命令。 Show动词明确表示“在屏幕上显示,没有其他可能性”。

     

动词为Show的命令未应用此检查。

Jeffrey Snover的博客帖子Write-Host Considered Harmful中,他声称​​ Write-Host几乎总是错误的做法,因为它会干扰自动化,并在诊断后提供了更多解释。以上是一个很好的总结。

答案 5 :(得分:0)

关于[Console] :: WriteLine()-如果要在CMD中使用管道(而不是在Powershell中),则应使用它。假设您希望ps1将大量数据流式传输到stdout,并使用其他实用程序来使用/转换它。如果在脚本中使用Write-Host,则速度会慢很多。