Istnieje wiele różnych sposobów wysyłania komunikatów. Jaka jest różnica pomiędzy skuteczne wyprowadzanie czegoś poprzez Write-Host
, Write-Output
lub [console]::WriteLine
?
Zauważam również, że jeśli użyję:
write-host "count=" + $count
+
Zostanie dołączona do wyjścia. Dlaczego tak jest Czy nie należy oceniać wyrażenia w celu utworzenia pojedynczego połączonego łańcucha przed jego zapisaniem?
powershell
Scott Langham
źródło
źródło
Write-Output
kiedy emitujesz wyniki.Write-Host
podczas wysyłania informacji o logowaniu. Nigdy nie należy używać[console]::writeline()
.[console]::writeline("hello world")
tym zrobićWrite-Host "hello world"
. Inną, lepszą, ostatnio stosowaną odpowiedzią jestwrite-host
owijanie,write-information
dzięki czemu jego dane są umieszczane w strumieniu,write-error
tak abyś mógł je przechwycić i wykorzystać w innym miejscu.[console]::writeline()
nie robi tegoOdpowiedzi:
Write-Output
powinien być używany, gdy chcesz wysłać dane w linii potoku, ale niekoniecznie chcesz je wyświetlić na ekranie. Potok ostatecznie zapisze go,out-default
jeśli nic innego go nie użyje wcześniej.Write-Host
należy stosować, gdy chcesz zrobić odwrotnie.[console]::WriteLine
jest zasadniczo tym, coWrite-Host
robi za kulisami.Uruchom ten kod demonstracyjny i sprawdź wynik.
Musisz zawrzeć operację konkatenacji w nawiasach, aby program PowerShell przetworzył konkatenację przed tokenizacją listy parametrów
Write-Host
lub użyj interpolacji łańcuchówBTW - Obejrzyj wideo Jeffreya Snovera wyjaśniającego, jak działa rurociąg. Kiedy zacząłem uczyć się programu PowerShell, znalazłem to najbardziej przydatne wyjaśnienie działania potoku.
źródło
Write-Output
jest domyślny, np. Jeśli masz PsObject i po prostu wyplujesz go na ekran, robiąc to$object
, faktycznie zrobi to samoWrite-Output $object
. Warto wspomniećWrite-Output
gdy to możliwe. Zobacz github.com/PoshCode/PowerShellPracticeAndStyle/issues/… > Użyj return tylko do zakończenia wykonywania. > Unikaj zapisu / zapisu (...). Zamiast tego, jeśli chcesz, aby dane wyjściowe były wyraźniejsze, po prostu przypisz dane wyjściowe do odpowiednio nazwanej zmiennej. i umieścił tę zmienną w linii, aby zasygnalizować jawne wyjście. > Write-Output -NoEnumerate jest uszkodzony w PowerShell 6 i działa już od 16 miesięcy lub dłużej - nie ma planu, aby to naprawić. Podsumowując:> NIE UŻYWAJ Write-Output - EVER.Oprócz tego, o czym wspomniał Andy, istnieje jeszcze jedna różnica, która może być ważna - write-host bezpośrednio zapisuje na hoście i nic nie zwraca, co oznacza, że nie można przekierować wyjścia, np. Do pliku.
Teraz uruchom w PowerShell:
Jak widać, nie można przekierować ich do pliku. Może to być zaskakujące dla kogoś, kto nie jest ostrożny.
Ale jeśli zostanie przełączony na użycie zapisu / wyjścia, przekierowanie będzie działało zgodnie z oczekiwaniami.
źródło
Oto inny sposób na osiągnięcie odpowiednika zapisu / wyjścia. Wystarczy wpisać ciąg w cudzysłów:
Możesz upewnić się, że działa to tak samo jak Zapis-Wyjście, uruchamiając ten eksperyment:
Pierwsze dwa wypiszą „bla bla” na out.txt, ale trzeci nie.
„help Write-Output” daje wskazówkę dotyczącą tego zachowania:
W takim przypadku sam ciąg „count = $ count” jest obiektem na końcu potoku i jest wyświetlany.
źródło
Dla zastosowań
Write-Host
,PSScriptAnalyzer
produkuje następującą diagnostykę:Więcej informacji znajduje się w dokumentacji tej reguły. Fragmenty dla potomności:
Jeffrey Snover ma wpis na blogu „ Host-host” uznany za szkodliwy, w którym twierdzi, że „ Host-host” jest prawie zawsze niewłaściwy, ponieważ zakłóca automatyzację i zapewnia więcej wyjaśnień związanych z diagnostyką, jednak powyższe jest dobrym podsumowaniem.
źródło
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 danymi rzeczywistymi muszę porzucić polecenia cmdlet i przejść bezpośrednio do poleceń niższego poziomu, aby uzyskać przyzwoitą wydajność ze skryptów.
źródło
Write-Output
iWrite-Host
służą różnym celom, więc nie ma sensu porównywać ich wydajności. Tak, bezpośrednie użycie typów .NET i ich metod jest szybsze, ale brakuje Ci funkcji wyższego poziomu, które mogą zapewnić cmdlety PowerShell.[Console]::WriteLine()
jest podobnyWrite-Host
w omawianej sprawie, ale nie będzie działać w każdych okolicznościach, ponieważ nie wszystkie hosty PowerShell są konsolami .Odnośnie [Console] :: WriteLine () - powinieneś go użyć, jeśli zamierzasz używać potoków w CMD (nie w PowerShell). Załóżmy, że chcesz, aby Twój PS1 przesyłał strumieniowo wiele danych do standardowego wyjścia, a także inne narzędzie do ich konsumpcji / transformacji. Jeśli użyjesz Write-Host w skrypcie, będzie on znacznie wolniejszy.
źródło