有许多不同的输出消息的方法。通过Write-Host, Write-Output或[console]::WriteLine输出之间的有效区别是什么?
我还注意到,如果我使用:
write-host "count=" + $count
+被包含在输出中。为什么?难道表达式不应该在输出之前求值以生成一个连接的字符串吗?
有许多不同的输出消息的方法。通过Write-Host, Write-Output或[console]::WriteLine输出之间的有效区别是什么?
我还注意到,如果我使用:
write-host "count=" + $count
+被包含在输出中。为什么?难道表达式不应该在输出之前求值以生成一个连接的字符串吗?
当前回答
当您希望在管道中发送数据,但不一定希望在屏幕上显示数据时,应该使用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)
# or
write-host "count=$count"
顺便说一句,观看杰弗里·斯诺弗解释管道如何运作的视频。当我开始学习PowerShell时,我发现这是对管道如何工作的最有用的解释。
其他回答
当您希望在管道中发送数据,但不一定希望在屏幕上显示数据时,应该使用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)
# or
write-host "count=$count"
顺便说一句,观看杰弗里·斯诺弗解释管道如何运作的视频。当我开始学习PowerShell时,我发现这是对管道如何工作的最有用的解释。
除了Andy提到的,还有一个重要的区别- write-host直接写入主机而不返回任何内容,这意味着你不能重定向输出,例如,到一个文件。
---- script a.ps1 ----
write-host "hello"
现在在PowerShell中运行:
PS> .\a.ps1 > someFile.txt
hello
PS> type someFile.txt
PS>
如前所述,您不能将它们重定向到文件中。这可能会让不小心的人感到惊讶。
但是如果切换到使用写输出,您将得到重定向工作。
关于[Console]::WriteLine() -如果你打算在CMD(不是在powershell)中使用管道,你应该使用它。假设您希望您的ps1将大量数据传输到标准输出,并使用其他实用程序来消费/转换这些数据。如果在脚本中使用Write-Host,则会慢得多。
这里有另一种实现等效写输出的方法。只要把你的字符串放在引号里:
"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”是管道末端的对象,并显示出来。
从我的测试中,Write-Output和[Console]::WriteLine()的性能比Write-Host要好得多。
这取决于你需要写多少文本,这可能很重要。
如果分别对Write-Host、Write-Output和[Console]::WriteLine()进行了5次测试,结果如下所示。
在我有限的经验中,我发现在处理任何类型的真实数据时,我需要放弃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