[powershell] “Write-Host”,“Write-Output”또는“[console] :: WriteLine”의 차이점은 무엇입니까?

메시지를 출력하는 방법에는 여러 가지가 있습니다. 를 통해 뭔가를 출력 사이의 효과 차이는 무엇입니까 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"

BTW- 파이프 라인 작동 방식을 설명하는 Jeffrey Snover 비디오 를 시청하십시오 . PowerShell 학습을 시작했을 때 파이프 라인 작동 방식에 대한 가장 유용한 설명 인 것으로 나타났습니다.


답변

Andy가 언급 한 것 외에도 중요한 다른 점이 있습니다. write-host는 호스트에 직접 쓰고 아무것도 반환하지 않습니다. 즉, 출력을 파일 등으로 리디렉션 할 수 없습니다.

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

이제 PowerShell에서 실행하십시오.

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

표시된 것처럼 파일로 리디렉션 할 수 없습니다. 조심하지 않는 사람에게는 놀라운 일입니다.

그러나 대신 쓰기 출력을 사용하도록 전환하면 예상대로 리디렉션이 작동합니다.


답변

Write-Output과 동등한 기능을 수행하는 또 다른 방법이 있습니다. 문자열을 따옴표로 묶으십시오.

"count=$count"

이 실험을 실행하여 Write-Output과 동일하게 작동하는지 확인할 수 있습니다.

"blah blah" > out.txt

Write-Output "blah blah" > out.txt

Write-Host "blah blah" > out.txt

처음 두 개는 “blah blah”를 out.txt로 출력하지만 세 번째는 출력하지 않습니다.

“help Write-Output”은이 동작에 대한 힌트를 제공합니다.

이 cmdlet은 일반적으로 콘솔에서 문자열 및 기타 개체를 표시하기 위해 스크립트에서 사용됩니다. 그러나 기본 동작은 파이프 라인 끝에 개체를 표시하는 것이므로 일반적으로 cmdlet을 사용할 필요는 없습니다.

이 경우 문자열 자체 “count = $ count”는 파이프 라인 끝에있는 개체이며 표시됩니다.


답변

의 용도를 들어 Write-Host, PSScriptAnalyzer다음과 같은 진단이 생성

사용하지 마십시오 Write-Host가없는 작품은 모든 호스트에, (PS 5.0 이전)에는 호스트 및 존재하지 작동합니까 억제 캡처 또는 리디렉션 할 수 없습니다 수 있기 때문이다. 대신, 사용 Write-Output, Write-Verbose또는 Write-Information.

자세한 내용은 해당 규칙 뒤에 있는 설명서 를 참조하십시오. 후손 발췌 :

의 사용은 Write-Host크게와 명령의 사용하지 않는 권장하지 않습니다 Show동사. Show동사는 명시 적으로 “다른 가능성으로 화면에 표시”를 의미한다.

Show동사가 있는 명령 에는이 검사가 적용되지 않습니다.

Jeffrey Snover는 Write-Host가 유해한 블로그 게시물을 작성했습니다. Write-Host는 자동화를 방해 하고 진단 뒤에 더 많은 설명을 제공 하기 때문에 Write-Host가 거의 항상 잘못된 일 이라고 주장 하지만 위의 요약입니다.


답변

필자의 테스트에서 Write-Output 및 [Console] :: WriteLine ()은 Write-Host보다 훨씬 우수합니다.

얼마나 많은 텍스트를 작성해야하는지에 따라 중요 할 수 있습니다.

아래는 5 개의 결과가 각각 Write-Host, Write-Output 및 [Console] :: WriteLine ()에 대해 테스트 된 경우입니다.

제한된 경험으로, 어떤 종류의 실제 데이터로 작업 할 때 cmdlet을 포기하고 스크립트에서 적절한 성능을 얻으려면 하위 수준 명령으로 바로 가야한다는 것을 알았습니다.

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


답변

[Console] :: WriteLine ()과 관련하여-powershell이 ​​아닌 CMD에서 파이프 라인을 사용하려는 경우이를 사용해야합니다. ps1이 많은 데이터를 stdout으로 스트리밍하고 다른 유틸리티가 그것을 소비 / 변환하기를 원한다고 가정 해보십시오. 스크립트에서 Write-Host를 사용하면 속도가 훨씬 느려집니다.


답변