2012-01-06 81 views
150

我试图去掌握P​​owerShell。我正在努力解决的一件简单的事情是,似乎有许多不同的方式来输出消息。我应该使用哪一个,有什么不同,是否有一种常规的方法?应该使用哪一个:“Write-Host”,“Write-Output”或“[console] :: WriteLine”?

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

write-host "count=" + $count 

+被包含在输出中。为什么?在表达式被写出之前,不应该评估表达式来产生单个串联的字符串吗?

+3

当你发出结果时,写入输出。 '写主机'当你发布日志信息。切勿使用'[console] :: writeline()'。 – JohnL 2013-08-31 02:01:41

+1

@JohnL为什么我们不应该使用[console] :: writeline()? – 2016-10-14 03:47:22

+3

@Backwards_Dave因为你有写主机....好吧,我可能一直有这样的印象,它展示了一个新的控制台窗口(这是很久以前)。这并没有发生,但事实是,它不是Powerhell的习惯用法,你无法用'Write-Host“hello所做的'[console] :: writeline(”hello world“)来做任何事情世界“'。另一个更好的最近可以应用的答案是'write-host'封装了'write-information',所以它的数据被放在一个像'write-error'这样的流上,这样你就可以捕获它并在其他地方使用它。 '[console] :: writeline()'不会那么做 – JohnL 2016-10-18 11:35:15

回答

219

Write-Output当您要发送在管线数据应被使用,但不一定要显示它在屏幕上。如果没有其他人首先使用它,管道将最终将其写入out-defaultWrite-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) 

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

+5

+1视频链接,好东西! – D3vtr0n 2012-12-04 18:54:47

+0

另一个为建议的链接+1,绝对是一个伟大的和有用的专家之间的谈话 – fra 2013-06-03 09:43:32

+0

在Azure WebJob [控制台] :: WriteLine的作品,但写主机将导致一个错误:Win32内部错误“句柄无效”0x6在为控制台输出缓冲区设置字符属性时发生。不要问我为什么。 – user1469065 2017-11-03 12:19:52

24

除了什么安迪提到的,还有另外一个差异可能是重要的 - 写主机直接写入到主机,并返回任何结果,这意味着你不能重定向输出,例如,一个文件。

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

现在在PowerShell中运行:

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

正如所看到的,你不能将其重定向到一个文件中。对于不小心的人来说,这可能令人惊讶。

但是,如果切换到使用写输出,而不是,你会得到重定向工作正常。

+0

如果您使用启动进程Powershell,则可以捕获写主机输出。\ a.ps1 -RedirectStandardOutput somefile.txt虽然(文件将位于SystemDefaultEncoding中)编码有问题。 – MKesper 2016-11-30 10:39:37

11

这里的另一种方式来完成写入产出的等价物。只要把你的字符串中引号:

"count=$count" 

您可以确保通过运行这个实验这部作品一样写输出:

"blah blah" > out.txt 

Write-Output "blah blah" > out.txt 

Write-Host "blah blah" > out.txt 

前两个将输出“等等等等”来了。 TXT,但第三个不会。

“帮忙写输出”给出了此行为的暗示:

This cmdlet is typically used in scripts to display strings and other objects on the console. However, because the default behavior is to display the objects at the end of a pipeline, it is generally not necessary to use the cmdlet.

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

3

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

取决于您需要写出多少文字,这可能很重要。

下面如果5次测试的结果为每个写主机,写输出和[控制台]:的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 
相关问题