2012-01-06 89 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 
相關問題