개요
자동 변수(automatic variable)는 PowerShell이 세션 시작 시 스스로 만들고 계속 값을 갱신하는 변수다. 06장의 $PROFILE, 03장에서 언급한 $PSVersionTable도 자동 변수의 일종이다. 이 장은 그중 가장 자주 쓰이는 변수들을 스크립팅·디버깅 관점에서 묶어 정리한다.
정신 모델은 “자동 변수는 대부분 읽기 전용으로 취급해야 하는 상태 스냅샷"이라는 것이다. 값을 직접 대입할 수 있는 것들도 있지만(예: $ErrorActionPreference는 별개의 환경설정 변수), 이 장에서 다루는 변수 대부분은 PowerShell 엔진이 갱신하는 값을 읽기만 하는 용도로 쓰인다. 표기상 대입이 가능하다고 해서 그렇게 해도 안전하다는 뜻은 아니다 — Microsoft 공식 문서도 하위 호환을 위해 쓰기가 허용될 뿐, 자동 변수는 개념적으로 읽기 전용으로 다뤄야 한다고 명시한다.
자주 쓰는 자동 변수
| 변수 | 내용 |
|---|---|
$_ (= $PSItem) | 파이프라인의 현재 객체(Where-Object, ForEach-Object 등의 스크립트블록 안에서) |
$null | 값이 없음을 나타내는 객체. 비교 시 항상 왼쪽에 두어야 컬렉션 필터링 부작용을 피한다(20장 참고) |
$true / $false | 불리언 리터럴 |
$Error | 세션에서 발생한 오류 객체의 배열. $Error[0]이 가장 최근 오류 |
$? | 마지막 명령의 성공 여부(Boolean). 네이티브 명령은 $LASTEXITCODE가 0일 때만 $true |
$LASTEXITCODE | 마지막으로 실행된 네이티브 프로그램 또는 PowerShell 스크립트의 종료 코드 |
$Matches | -match/-notmatch 연산자가 스칼라 입력에서 매칭됐을 때 캡처 그룹을 담는 해시테이블 |
$PSVersionTable | 현재 세션의 PowerShell 버전·에디션·플랫폼 정보(01장 참고) |
$PSScriptRoot | 실행 중인 스크립트가 위치한 디렉터리의 전체 경로 |
$args | 함수·스크립트에 전달된, param으로 선언되지 않은 매개변수 값 배열 |
$IsWindows / $IsLinux / $IsMacOS | 현재 세션이 실행 중인 운영체제(PowerShell 6+) |
예시
| |
주의사항·함정
$?는 예상보다 미묘하게 동작한다: 함수 안에서 Write-Error를 호출해도, 그 함수를 호출한 바깥에서 확인하는 $?는 다시 True로 리셋될 수 있다(함수가 정상적으로 반환됐기 때문). 함수 내부의 실패 여부를 정확히 전달하려면 $PSCmdlet.WriteError()를 쓰거나 명시적으로 상태를 반환해야 한다.
$LASTEXITCODE는 네이티브 명령에만 의미가 있다: 순수 PowerShell cmdlet은 종료 코드를 반환하지 않으므로, cmdlet만 실행한 직후 $LASTEXITCODE를 확인하면 그 이전에 실행된 네이티브 명령의 값이 그대로 남아 있을 수 있다. cmdlet 성공 여부는 $?나 try/catch로 확인해야 한다.
$Matches는 매칭 실패 시 이전 값을 그대로 유지한다: -match가 거짓을 반환한 경우 $Matches는 초기화되지 않고 이전 매칭 결과를 그대로 들고 있다. -match 호출 직후 if 조건 안에서만 $Matches를 참조하는 습관을 들이면 이 문제를 피할 수 있다.
자동 변수 이름으로 새 변수를 만들면 안 된다: $Matches, $Error, $_ 같은 이름으로 직접 변수를 만들면 PowerShell 엔진이 관리하는 값과 충돌해 예측하기 어려운 동작을 일으킨다.
이식성: Bash의 $?(마지막 종료 코드), $_(마지막 인자 또는 파이프라인 컨텍스트에 따라 다름)와 이름은 비슷하지만 의미가 다르다 — PowerShell의 $?는 Boolean이고 $_는 파이프라인 객체 자체를 가리킨다. CMD의 %ERRORLEVEL%이 PowerShell의 $LASTEXITCODE와 가장 가깝게 대응한다.
![Featured image of post [PowerShell] 24. 자동 변수 총정리 — $_, $null, $Error, $LASTEXITCODE](/post/powershell/automatic-variables-powershell-underscore-null/wordcloud_hu_fc36a736f816aa28.webp)
![[PowerShell] 22. -split/-join 연산자](/post/powershell/split-join-operators-powershell-strings/wordcloud_hu_284bbfdffb9b3b18.webp)
![[PowerShell] 23. 타입 캐스팅과 [type] 접근자](/post/powershell/type-casting-type-accelerator-powershell/wordcloud_hu_e3ac5e77eecdb3c5.webp)
![[PowerShell] 24. 자동 변수 총정리 — $_, $null, $Error, $LASTEXITCODE](/post/powershell/automatic-variables-powershell-underscore-null/wordcloud_hu_fed154e062984d25.webp)
![[PowerShell] 25. 공통 매개변수 — -Verbose/-Debug/-ErrorAction/-OutVariable](/post/powershell/common-parameters-verbose-debug-erroraction-powershell/wordcloud_hu_af2f3755ebbce019.webp)
![[PowerShell] 26. -WhatIf/-Confirm과 ShouldProcess](/post/powershell/whatif-confirm-shouldprocess-powershell/wordcloud_hu_41a4dbb601ca47c7.webp)
![[PowerShell] 65. try/catch/finally — 예외 처리](/post/powershell/try-catch-finally-exception-powershell/wordcloud_hu_a322ce3572196406.webp)
![[PowerShell] 70. Set-PSBreakpoint — 스크립트 디버깅](/post/powershell/set-psbreakpoint-debugging-powershell/wordcloud_hu_ce0529ad2ee3374e.webp)
![[PowerShell] 18. Tee-Object — 파이프라인 분기](/post/powershell/tee-object-command-pipeline-branch-powershell/wordcloud_hu_26906348220bc5ce.webp)
![[PowerShell] 30. PSDrive와 프로바이더 개념](/post/powershell/psdrive-provider-concept-powershell/wordcloud_hu_48d84a64f7474c4.webp)