개요
Write-Host와 Write-Output은 둘 다 화면에 텍스트를 표시할 수 있어서 같은 일을 하는 것처럼 보이지만, 실제로는 서로 다른 출력 스트림에 쓴다. 이 차이를 모르고 스크립트를 짜면 “화면에는 잘 보이는데 결과를 변수에 담거나 파이프로 넘기면 아무것도 안 잡힌다"는 대표적인 초보자 함정에 빠진다.
기본 개념
PowerShell은 출력을 용도별로 6개의 스트림으로 나눈다.
| 번호 | 스트림 | 관련 cmdlet |
|---|---|---|
| 1 | 성공(Success) | Write-Output(또는 암묵적 출력) |
| 2 | 오류(Error) | Write-Error |
| 3 | 경고(Warning) | Write-Warning |
| 4 | 상세(Verbose) | Write-Verbose |
| 5 | 디버그(Debug) | Write-Debug |
| 6 | 정보(Information) | Write-Information, 그리고 내부적으로 Write-Host |
Write-Output은 성공 스트림(파이프라인)에 객체를 보낸다 — 이것이 Where-Object·Select-Object 등 이 컬렉션에서 다룬 모든 cmdlet이 주고받는 바로 그 스트림이다. 반면 Windows PowerShell 5.0부터 Write-Host는 정보 스트림에 쓰는 Write-Information의 래퍼로 재구현됐다 — 화면(호스트)에 표시하는 것이 목적이고, 파이프라인으로는 흘러가지 않는다.
종류/세부
파이프라인 캡처 가능 여부
| |
암묵적 출력 — Write-Output은 대체로 생략한다
파이프라인 끝에서 자동으로 출력되는 값(함수의 마지막 식, Get-Process 등)에는 Write-Output을 굳이 쓸 필요가 없다. Get-Process | Write-Output은 그냥 Get-Process와 동등하며, PowerShell 커뮤니티 관례상 이런 명시적 호출은 불필요한 코드로 간주된다.
스트림별로 캡처하는 법
| |
주의사항·함정
“화면에 보이니까 결과값이다"는 착각이 가장 흔한 오개념이다: Write-Host로 출력한 값은 사람 눈에는 똑같이 보여도 함수의 반환값이나 파이프라인 결과에는 절대 포함되지 않는다. 함수 안에서 진행 상황을 사람에게 보여주고 싶으면 Write-Host(또는 Write-Verbose)를, 함수의 실제 결과를 반환하고 싶으면 값 자체를 그대로 두거나 Write-Output 없이 마지막 식으로 남기면 된다.
$InformationPreference/-InformationAction은 Write-Host를 완전히는 제어하지 못한다: Write-Host가 Write-Information의 래퍼이긴 하지만, -InformationAction Ignore를 제외한 다른 값들은 Write-Host 메시지의 표시 여부에 영향을 주지 않는다 — 하위 호환성을 위해 남겨진 예외적 동작이다. 확실히 숨기려면 -InformationAction Ignore나 6> $null 리다이렉션을 쓴다.
해시테이블처럼 복잡한 객체를 Write-Host에 그냥 넘기면 ToString() 결과만 보인다: @{a=1;b=2} | Write-Host는 System.Collections.Hashtable이라는 의미 없는 문자열만 출력한다. 의미 있는 텍스트가 필요하면 문자열 보간이나 -f 연산자로 직접 포맷하거나, Out-String을 거친 뒤 Write-Host에 넘긴다.
이식성: Bash의 echo는 표준 출력(stdout)에 쓰고 그대로 파이프로 흘러가므로 CMD·Bash 사용자는 “화면에 출력 = 파이프로도 전달"이라는 습관에 익숙하다. PowerShell에서는 이 등식이 성립하지 않는다는 것이 이 컬렉션 전체에서 가장 자주 반복해서 짚는 함정이다.
![Featured image of post [PowerShell] 29. Write-Host vs Write-Output — 출력 스트림 오개념 정리](/post/powershell/write-host-vs-write-output-streams-powershell/wordcloud_hu_7c827105cb317cb9.webp)
![[PowerShell] 27. New-Object와 [PSCustomObject]](/post/powershell/new-object-pscustomobject-powershell/wordcloud_hu_a77220cb464cca6d.webp)
![[PowerShell] 28. Add-Member — 커스텀 객체에 속성·메서드 추가](/post/powershell/add-member-command-custom-object-properties-powershell/wordcloud_hu_5d862fe677def637.webp)
![[PowerShell] 29. Write-Host vs Write-Output — 출력 스트림 오개념 정리](/post/powershell/write-host-vs-write-output-streams-powershell/wordcloud_hu_cd68b845a7c59766.webp)
![[PowerShell] 30. PSDrive와 프로바이더 개념](/post/powershell/psdrive-provider-concept-powershell/wordcloud_hu_48d84a64f7474c4.webp)
![[PowerShell] 31. Get-ChildItem — 파일·디렉터리 목록](/post/powershell/get-childitem-command-file-directory-list-powershell/wordcloud_hu_3e00080e70b06aa7.webp)
![[PowerShell] 18. Tee-Object — 파이프라인 분기](/post/powershell/tee-object-command-pipeline-branch-powershell/wordcloud_hu_26906348220bc5ce.webp)
![[PowerShell] 50. ConvertTo-Html과 Out-File](/post/powershell/convertto-html-out-file-powershell/wordcloud_hu_d068d41aa5ff8785.webp)
![[PowerShell] 68. Write-Verbose/Debug/Warning/Information](/post/powershell/write-verbose-debug-warning-powershell/wordcloud_hu_23130845671cc57.webp)
![[PowerShell] 00. 과정 개요와 커리큘럼](/post/powershell/getting-started-powershell/wordcloud_hu_15979a96cd2a594f.webp)
![[PowerShell] 100. Get-Credential과 PSCredential 객체](/post/powershell/get-credential-pscredential-object-powershell/wordcloud_hu_e8db052a57f9c242.webp)