В чем разница между «Write-Host», «Write-Output» или «[console] :: WriteLine»?

Вопрос:Существует несколько способов вывода сообщений. Какова эффективная разница между выводом чего-либо через Write-Host, Write-Output или [console]::WriteLine? Я также заметил, что если я использую: write-host "count=" + $count + включается в вывод. Почему так? Разве выражение не должно быть оценено, чтобы произвести единственную объединенную строку прежде, чем это будет записано? Лучший ответ: Write-Output следует использовать, когда

Вопрос:

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

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

write-host «count=» + $count

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

Лучший ответ:

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) # or write-host «count=$count»

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

Ответ №1

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

—- script a.ps1 —- write-host «hello»

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

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

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

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

Ответ №2

Здесь другой способ выполнить эквивалент Write-Output. Просто введите свою строку в кавычки:

«count=$count»

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

«blah blah» > out.txt Write-Output «blah blah» > out.txt Write-Host «blah blah» > out.txt

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

“help Write-Output” дает подсказку такого поведения:

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

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

Ответ №3

Из моего теста 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 Ответ №4

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

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

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

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

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

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

Ответ №5

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

Оцените статью
Добавить комментарий