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


193

메시지를 출력하는 방법에는 여러 가지가 있습니다. 를 통해 뭔가를 출력 사이의 효과 차이는 무엇입니까 Write-Host, Write-Output또는은 [console]::WriteLine?

또한 사용하면 다음을 알 수 있습니다.

write-host "count=" + $count

+출력에 포함됩니다. 왜 그래? 연결하기 전에 하나의 연결된 문자열을 생성하도록 표현식을 평가해서는 안됩니까?


4
Write-Output당신이 결과를 방출 할 때. Write-Host로깅 정보를 방출 할 때 사용하지 마십시오 [console]::writeline().
JohnL

2
@JohnL 왜 우리는 [console] :: writeline ()을 사용해서는 안됩니까?
David Klempfner

3
@Backwards_Dave Write-Host를 가지고 있기 때문에 .. 네, 새로운 콘솔 창을 보여줬다는 느낌이 들었습니다. 그런 일은 일어나지 않지만 파워 쉘 관용구가 아니며 실제로 [console]::writeline("hello world")할 수없는 일은 없습니다 Write-Host "hello world". 더 좋고 더 최근에 적용 가능한 또 다른 대답은 write-host랩핑 write-information하여 데이터를 스트림에 배치하여 데이터 write-error를 캡처하여 다른 곳에서 사용할 수 있다는 것입니다. [console]::writeline()그렇게하지 마십시오
JohnL

답변:


268

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 학습을 시작했을 때 파이프 라인 작동 방식에 대한 가장 유용한 설명 인 것으로 나타났습니다.


Azure WebJob [console] :: WriteLine에서 작동하지만 Write-Host에서 오류가 발생합니다. 콘솔 출력 버퍼의 문자 속성을 설정하는 동안 Win32 내부 오류 "핸들이 잘못되었습니다"0x6이 발생했습니다. 이유를 묻지 마십시오.
Gil Roitto

내가 틀렸다면 수정하십시오. Write-Output예를 들어 PsObject가 있고 이것을 수행하여 화면에 뱉어내는 것이 기본값 이라고 생각 $object합니다 Write-Output $object. 실제로 this와 동일한 작업을 수행합니다 . 언급 할만큼 가치가 될 수 있음
계산법 캐년

1
새로운 지침이 Write-Output있습니다. 가능하면 사용하지 마십시오 . github.com/PoshCode/PowerShellPracticeAndStyle/issues/…를 참조하십시오 . > 실행 종료에만 return을 사용하십시오. > 쓰기 출력 (...)을 피하십시오. 대신 출력을 더 명확하게하려면 출력을 관련 이름이 지정된 변수에 지정하십시오. 명시적인 출력을 알리기 위해 변수를 한 줄에 넣습니다. > Write-Output -NoEnumerate는 PowerShell 6에서 손상되었으며 16 개월 이상 지속되었으며이를 해결할 계획이 없습니다. 요약 :> 쓰기 출력을 사용하지 마십시오.
Jeroen Wiert Pluimers

28

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

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

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

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

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

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


Start-Process Powershell을 사용하면 쓰기 호스트 출력을 캡처 할 수 있습니다. \ a.ps1 -RedirectStandardOutput somefile.txt 인코딩에 문제가 있습니다 (파일은 SystemDefaultEncoding에 있음).
MKesper

16

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"는 파이프 라인 끝에있는 개체이며 표시됩니다.


6

의 용도를 들어 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가 거의 항상 잘못된 일 이라고 주장 하지만 위의 요약입니다.


3

필자의 테스트에서 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

1
Write-OutputWrite-Host다른 용도로 사용하므로 성능을 비교 아무 문제가 없다. 예. .NET 유형과 해당 방법을 직접 사용하는 것이 더 빠르지 만 PowerShell cmdlet이 제공 할 수있는 고급 기능은 빠집니다. [Console]::WriteLine()이 경우와 비슷 Write-Host하지만 모든 PowerShell 호스트가 콘솔 이 아니기 때문에 모든 상황에서 작동하지는 않습니다 .
mklement0

0

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

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.