Jaka jest różnica między "Write-Host", "Write-Output" lub "[console]:: WriteLine"?

Istnieje wiele różnych sposobów wysyłania wiadomości. Jaka jest skuteczna różnica między wyprowadzaniem czegoś przez Write-Host, Write-Output, albo [console]::WriteLine?

Zauważam również, że jeśli używam:

write-host "count=" + $count

+ zostanie dołączony do wyjścia. Dlaczego? Czy wyrażenie nie powinno być ocenione do wytworzenia pojedynczego skonkatenowanego ciągu znaków przed jego wypisaniem?

 200
Author: Scott Langham, 2012-01-06

6 answers

Write-Output powinien być używany, gdy chcesz wysłać dane w linii rury, ale niekoniecznie chcesz wyświetlać je na ekranie. Rurociąg w końcu zapisze go do out-default, jeśli nic innego nie użyje go wcześniej.

Write-Host powinien być stosowany, gdy chcesz zrobić odwrotnie.

[console]::WriteLine jest w zasadzie tym, co Write-Host robi za kulisami.

Uruchom ten kod demonstracyjny i sprawdź wynik.

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 

Musisz dołączyć operację konkatenacji w nawiasach, aby PowerShell przetwarza konkatenację przed tokenizacją listy parametrów dla Write-Host lub używa interpolacji łańcuchowej

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

BTW-obejrzyj ten filmik z Jeffreyem Snoverem wyjaśniający jak działa rurociąg. Kiedy zacząłem uczyć się PowerShell, uznałem, że jest to najbardziej przydatne wyjaśnienie działania potoku.

 277
Author: Andy Arismendi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-09-06 11:17:30

Poza tym, o czym wspomniał Andy, istnieje inna różnica, która może być ważna - write-host bezpośrednio zapisuje do hosta i nic nie zwraca, co oznacza, że nie można przekierować wyjścia, np. do pliku.

---- script a.ps1 ----
write-host "hello"
Teraz uruchom w PowerShell:
PS> .\a.ps1 > someFile.txt
hello
PS> type someFile.txt
PS>

Jak widać, nie można przekierować ich do pliku. To może zaskakujące dla kogoś, kto nie jest ostrożny.

Ale po przełączeniu na użycie write-output, przekierowanie będzie działać zgodnie z oczekiwaniami.

 28
Author: KFL,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-23 01:02:44

Oto inny sposób na uzyskanie odpowiednika zapisu-wyjścia. Po prostu umieść swój ciąg w cudzysłowach:

"count=$count"

Możesz upewnić się, że działa to tak samo jak Write-Output, uruchamiając ten eksperyment:

"blah blah" > out.txt

Write-Output "blah blah" > out.txt

Write-Host "blah blah" > out.txt

Pierwsze dwa wyjdą "bla bla", aby wyjść.txt, ale trzeci nie.

"help Write-Output" daje podpowiedź o tym zachowaniu:

Ten cmdlet jest zwykle używany w skryptach do wyświetlania łańcuchów i innych obiekty na konsoli. Jednakże, ponieważ domyślnym zachowaniem jest wyświetlanie obiektów na końcu potoku, generalnie nie jest niezbędne do korzystania z cmdlet.

W tym przypadku łańcuch znaków "count=$count" jest obiektem na końcu potoku i jest wyświetlany.

 16
Author: FarmerBob,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-07 19:09:38

Do zastosowań Write-Host, PSScriptAnalyzer produkuje następującą diagnostykę:

Unikaj używania Write-Host, ponieważ może nie działać na wszystkich hostach, nie działa, gdy nie ma hosta i (przed PS 5.0) nie może być tłumiony, przechwytywany lub przekierowywany. Zamiast tego użyj Write-Output, Write-Verbose, lub Write-Information.

Zobacz dokumentację kryjącą się za tą zasadą, aby uzyskać więcej informacji. Fragmenty dla potomności:

Stosowanie Write-Host jest bardzo odradzane, chyba że w użycie poleceń z czasownikiem Show. Czasownik Show wyraźnie oznacza "Pokaż na ekranie, bez innych możliwości".

Polecenia z czasownikiem Show nie mają tej opcji.

Jeffrey Snover ma post na blogu Write-Host uważany za szkodliwy , w którym twierdzi Write-Host jest prawie zawsze niewłaściwą rzeczą, ponieważ zakłóca automatyzację i zapewnia więcej wyjaśnień za diagnostyką, jednak powyższe jest dobrym rozwiązaniem. podsumowanie.

 7
Author: Drew Noakes,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-01-10 10:40:14

Z moich testów Write-Output i [Console]::WriteLine() działają znacznie lepiej niż Write-Host.

W zależności od tego, ile tekstu trzeba napisać, może to być ważne.

Poniżej, jeśli wynik 5 testów dla Write-Host, Write-Output i [Console]::WriteLine().

Z mojego ograniczonego doświadczenia wynika, że podczas pracy z dowolnymi danymi z prawdziwego świata muszę porzucić cmdlety i przejść od razu do poleceń niższego poziomu, aby uzyskać przyzwoitą wydajność z mojego Skrypty.

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
 3
Author: tom,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-15 08:31:13

Regarding [Console]:: WriteLine() - powinieneś go użyć, jeśli zamierzasz używać pipelines w CMD (nie w powershell). Powiedzmy, że chcesz, aby twój ps1 przesyłał strumieniowo wiele danych na stdout i inne narzędzie do ich zużywania/przekształcania. Jeśli użyjesz Write-Host w skrypcie, będzie to znacznie wolniejsze.

 0
Author: Mike Twc,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-12-13 18:02:19