Que dois-je utiliser: "Write-Host", "Write-Output", ou "[console]::WriteLine"?

j'essaie de m'attaquer à PowerShell. Une chose simple que j'ai du mal à comprendre est qu'il semble y avoir un certain nombre de façons différentes de produire des messages. Qui dois-je utiliser et quelle est la différence, et s'il y a une façon traditionnelle de faire?

je remarque aussi que si j'utilise:

write-host "count=" + $count

Le + est inclus dans la sortie. Pourquoi? L'expression ne devrait-elle pas être évaluée pour produire un seul concaténé une corde avant qu'elle soit écrite?

167
demandé sur Peter Mortensen 2012-01-06 13:02:37

4 réponses

Write-Output doit être utilisé lorsque vous voulez envoyer des données sur dans la conduite, mais pas nécessairement vouloir l'afficher à l'écran. Le pipeline écrira éventuellement out-default si rien d'autre ne l'utilise en premier. Write-Host doit être utilisé quand vous voulez faire le contraire. [console]::WriteLine est essentiellement ce que Write-Host fait dans les coulisses.

exécutez ce code de démonstration et examinez le résultat.

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 

besoin de mettre l'opération de concaténation entre parenthèses pour que PowerShell traite la concaténation avant de tokenizer la liste de paramètres pour Write-Host .

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

BTW - Regarder cette vidéo de Jeffrey snover fait en expliquant comment le pipeline fonctionne. Lorsque j'ai commencé à apprendre PowerShell, j'ai trouvé que c'était l'explication la plus utile du fonctionnement du pipeline.

234
répondu Andy Arismendi 2013-08-31 10:21:00

outre ce Qu'a mentionné Andy, il y a une autre différence qui pourrait être importante - écrire-l'hôte écrit directement à l'hôte et ne lui renvoie rien, ce qui signifie que vous ne pouvez pas rediriger la sortie, par exemple, vers un fichier.

---- script a.ps1 ----
write-host "hello"

fonctionne maintenant en PowerShell:

PS> .\a.ps1 > someFile.txt
hello
PS> type someFile.txt
PS>

comme vu, vous ne pouvez pas les rediriger dans un fichier. Cela peut surprendre pour quelqu'un qui n'est pas prudent.

mais si commuté pour utiliser l'écriture-sortie au lieu de cela, vous obtiendrez redirection fonctionnant comme prévu.

26
répondu KFL 2013-05-23 01:02:44

Voici une autre façon d'accomplir l'équivalent de L'écriture-sortie. Il suffit de mettre votre chaîne de caractères entre guillemets:

"count=$count"

vous pouvez vous assurer que cela fonctionne de la même façon que L'écriture-sortie en exécutant cette expérience:

"blah blah" > out.txt

Write-Output "blah blah" > out.txt

Write-Host "blah blah" > out.txt

les deux premiers sortiront "bla bla".txt, mais pas le troisième.

"help Write-Output" donne un indice de ce comportement:

ce cmdlet est généralement utilisé dans les scripts pour afficher les chaînes et autres les objets sur la console. Cependant, parce que le comportement par défaut est de afficher les objets à la fin d'un pipeline, il n'est généralement pas nécessaire pour utiliser l'applet de commande.

Dans ce cas, la chaîne elle-même "count=$count" est l'objet à la fin d'un pipeline, et est affiché.

14
répondu FarmerBob 2017-10-07 19:09:38

De mon test d'Écriture de Sortie et [Console]::WriteLine() effectuer beaucoup mieux que Write-Host.

selon la quantité de texte que vous devez écrire, cela peut être important.

ci-dessous si le résultat de 5 tests chacun pour Write-Host, Write-Output et [Console]::WriteLine().

dans mon expérience limitée, j'ai trouvé que lorsque je travaille avec n'importe quelle sorte de données du monde réel, je dois abandonner les cmdlets et aller directement vers le bas les commandes de niveau pour obtenir de rendement décent de mes scripts.

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
répondu tom 2017-04-15 08:31:13