В чем разница между «Write-Host», «Write-Output» или «[console] :: WriteLine»? - PullRequest
179 голосов
/ 06 января 2012

Существует несколько способов вывода сообщений. Какова эффективная разница между выводом чего-либо через Write-Host, Write-Output или [console]::WriteLine?

Я также заметил, что если я использую:

write-host "count=" + $count

+ включается в вывод. Почему это? Разве выражение не должно быть оценено, чтобы произвести единственную объединенную строку, прежде чем оно будет записано?

Ответы [ 6 ]

250 голосов
/ 06 января 2012

Write-Output следует использовать, если вы хотите отправить данные по конвейеру, но не обязательно хотите отобразить их на экране. Конвейер в конечном итоге запишет его в out-default, если больше никто не использует его первым.

Write-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)

Кстати - посмотрите это видео Джеффри Сновера, объясняющее, как работает конвейер. Когда я начал изучать PowerShell, я обнаружил, что это наиболее полезное объяснение того, как работает конвейер.

28 голосов
/ 23 мая 2013

Помимо того, что упомянул Энди, есть еще одно отличие, которое может иметь важное значение - write-host напрямую пишет на хост и ничего не возвращает, а это означает, что вы не можете перенаправить вывод, например, в файл.1002 *

Теперь запустите в PowerShell:

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

Как видно, вы не можете перенаправить их в файл.Это может быть удивительно для тех, кто не осторожен.

Но если вместо этого переключиться на использование записи-вывода, перенаправление будет работать должным образом.

15 голосов
/ 31 августа 2013

Вот еще один способ сделать эквивалент записи-вывода. Просто поместите вашу строку в кавычки:

"count=$count"

Вы можете убедиться, что это работает так же, как запись-вывод, запустив этот эксперимент:

"blah blah" > out.txt

Write-Output "blah blah" > out.txt

Write-Host "blah blah" > out.txt

Первые два будут выводить «бла-бла» в out.txt, а третье - нет.

«Help Write-Output» дает подсказку о таком поведении:

Этот командлет обычно используется в сценариях для отображения строк и других объекты на консоли. Тем не менее, поскольку поведение по умолчанию отображать объекты в конце конвейера, это обычно не необходимо использовать командлет.

В этом случае сама строка "count = $ count" является объектом в конце конвейера и отображается.

3 голосов
/ 15 апреля 2017

Из моего тестирования Write-Output и [Console] :: WriteLine () работают намного лучше, чем Write-Host.

В зависимости от того, сколько текста вам нужно выписать, это может быть важно.

Ниже, если результат 5 тестов каждый для Write-Host, Write-Output и [Console] :: WriteLine ().

В моем ограниченном опыте я обнаружил, работая с любым видомданные реального мира, мне нужно отказаться от командлетов и сразу перейти к командам более низкого уровня, чтобы добиться приличной производительности от моих сценариев.

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
1 голос
/ 10 января 2019

При использовании Write-Host, PSScriptAnalyzer выдает следующую диагностику:

Избегайте использования Write-Host, поскольку оно может работать не на всех хостах, не работаеткогда нет хоста и (до PS 5.0) не может быть подавлен, перехвачен или перенаправлен.Вместо этого используйте Write-Output, Write-Verbose или Write-Information.

См. Документацию за этим правилом для получения дополнительной информации.Выдержки для потомков:

Использование Write-Host крайне не рекомендуется, если не используются команды с глаголом Show.Глагол Show явно означает «показать на экране, без других возможностей».

Команды с глаголом Show не применяют эту проверку.

Джеффри Сноверимеет запись в блоге Write-Host считается вредной , в которой он заявляет Write-Host почти всегда неправильно, потому что это мешает автоматизации и предоставляет больше объяснений, стоящих за диагностикой, однакоВыше приведено хорошее резюме.

0 голосов
/ 13 декабря 2018

Относительно [Console] :: WriteLine () - вы должны использовать его, если собираетесь использовать конвейеры в CMD (не в powershell). Скажем, вы хотите, чтобы ваш ps1 передавал много данных на стандартный вывод, а некоторые другие утилиты использовали их для преобразования / преобразования. Если вы используете Write-Host в скрипте, это будет намного медленнее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...