写主机和写输出的结果有什么不同?

问题描述:

我是PowerShell的新手,在做一些代码的时候,我经历了这件事。 虽然我使用Write-HostWrite-Output执行相同的查询,我得到不同的结果:写主机和写输出的结果有什么不同?

PS> Write-Output $PSVersionTable                             

Name       Value                                    
----       -----                                    
PSVersion      5.0.10586.117                                   
PSCompatibleVersions   {1.0, 2.0, 3.0, 4.0...}                                
BuildVersion     10.0.10586.117 
CLRVersion      4.0.30319.17929 
WSManStackVersion    3.0                                     
PSRemotingProtocolVersion  2.3                                     
SerializationVersion   1.1.0.1                                    

PS> Write-Host $PSVersionTable                             
System.Collections.DictionaryEntry System.Collections.DictionaryEntry System.Collections.DictionaryEntry System.Collections.DictionaryEntry System.Collections.DictionaryEntry System.Collections.DictionaryEntry System.Collections.DictionaryEntry System.Collections.DictionaryEntry System.Collections.DictionaryEntry 

在这里做一个谷歌搜索时是两个顶部的结果:

PowerShell difference between Write-Host and Write-Output?

Which should I use: "Write-Host", "Write-Output", or "[console]::WriteLine"?

*编辑: Write-Host不支持数据类型$PSVersionTableWrite-Output。看看哪一个支持您可以使用的数据类型

Get-Help Write-Host 
Get-Help Write-Output 
+0

埃里克我已确定这些。请检查我上传的图片以及问题。 Thnx反正 – Kaushal

+0

啊,我没有看到图片,我现在在我的答案中加了几行。 –

+0

Quibble:不是'Write-Host'不支持'[System.Management.Automation.PSVersionHashTable]','$ PSVersionTable'的数据类型;它只是以一种对人类观察者无益的方式将其串联起来,主要是因为它通常用于打印_strings_; Write-Output“和”Write-Output“都支持(接受)_any_类型的实例,但是(a)它们的字符串化方式不同,(b) - 更重要的是 - **'Write-Output'和'Write-主持人服务的目的非常不同**(正如链接文章解释的那样,但本身并不是你的答案)。 – mklement0

而另一篇好文章: Which Write Is Right For PowerShell?

总之$ PSVersionTable返回哈希表(对象的集合)。 Write-host命令试图将所有内容都转换为字符串,然后在控制台显示它,但不能将整个散列表直接转换为字符串。

写输出直接发送这个哈希表到控制台而不尝试改变它。

重要的区别

写写输出对象到管道,从而它的输入下一个命令可以接受它。 虽然写主机只是直接写入控制台。

在您的例子

写输出将对象写入到管道,和Out-默认(在管道的端部隐藏)将在任一表或列表中显示的对象的值。

写主机直接写入控制台,而不是在管道末端使用缺省cmdlet Out-default。换句话说,写主机不会向管道写入任何内容,只显示他在控制台上看到的内容。 这就是为什么您可以将参数-foregroundcolor添加到Write-Host cmdlet,而不是写入输出小命令。

写主机在调试时很有用,而且您需要以不同的颜色显示文本。

你可以简单地用

Write-Output "Hello World" | Get-Member 

测试,我们可以瑟,这是以System.String对象。

如果我们运行:

Write-Host "Hello World" | Get-Member 

我们得到一个错误: 克:您必须指定对象为获取会员cmdlet的...

这听起来像你已经知道Write-HostWrite-Output有不同的目的。简而言之:

  • 为了产生(数据)输出,只需使用一个命令或表达式原样,其隐含其输出到成功(数据)输出流 - 明确使用的Write-Output很少需要

    • 相反的Write-Output $PSVersionTable,你可以简单地通过自身使用$PSVersionTable
  • Write-Host,在PSv4-,直接把主机(例如,控制台)打印,绕过PowerShell的输出流,这是为什么it should generally be avoided。虽然自从V5集成到PowerShell的输出流,通过流#6,这是更好地使用它的后继者,Write-Information - 除非你需要制作彩色控制台输出,用于创建用户界面。


为了解释控制台输出的区别:就像隐输出

  • Write-Output使用PowerShell的default output formatting,它通常提供一个更友好的表示不只是拨打.ToString()基础.NET类型实例 - 见Get-Help about_Format.ps1xml

    • $PSVersionTable.GetType().FullName告诉我们,$PSVersionTable[System.Management.Automation.PSVersionHashTable]一个实例,从[System.Collections.Hashtable],这PowerShell的默认格式呈现在2列的表格布局派生。
  • Write-Host基本要求只是.ToString()其参数,在许多情况下,只打印是一个对象的完整类型名称。

    • [System.Management.Automation.PSVersionHashTable]实例调用.ToString()会产生只是System.Management.Automation.PSVersionHashTable
      但是,Write-Host prints the elements of objects that support the [IEnumerable] interface individually

    • 因此,每个条目$PSVersionTable分开打印,由于条目是[System.Collections.DictionaryEntry]类型,这也stringifies简单类型的全名 - System.Collections.DictionaryEntry - 你得到这些字符串的空格分隔的列表(因为Write-Host通常会将不同的输出分别以单个空格连接)。

注意,您可以明确要求PowerShell的默认输出通过Out-String cmdlet的格式化的字符串表示。

因此,除了从该流的集成方面,以下Write-Host命令产生相同控制台输出作为Write-Output $PSVersionTable(或简称:$PSVersionTable):

Write-Host ($PSVersionTable | Out-String)