개요
함수는 function 키워드로 이름을 붙인 재사용 가능한 명령 블록이다. 53장에서 스크립트 전체를 하나의 단위로 실행하는 법을 배웠다면, 이 장은 스크립트 안에서 반복되는 로직을 이름 붙인 단위로 나누는 법을 다룬다. 잘 만든 함수는 사용하는 쪽에서 보면 실제 cmdlet과 거의 구분되지 않는다.
정신 모델은 “함수는 이름이 붙은 스크립트 블록이고, param()은 그 함수가 받을 입력의 이름표"라는 것이다. 함수 안의 모든 문장이 만들어내는 출력은 파이프라인으로 흘러나가 자동으로 함수의 반환값이 된다 — return은 선택 사항이며, 값을 계산하는 명령문이 있다면 그 자체로 이미 출력이다.
사용법
| |
종류
| 요소 | 설명 |
|---|---|
| 명명된 매개변수 | param()으로 선언, -이름 값 형태로 호출 |
| 위치 매개변수 | param() 순서대로 이름 없이 값만 전달 가능(41장의 위치 매개변수 개념과 동일) |
$args | param()으로 선언되지 않은 나머지 인자를 담는 자동 배열(고급 함수에서는 사용 불가) |
[switch] 매개변수 | 값 없이 존재 여부로 참/거짓을 전달(26장의 -WhatIf도 이 방식) |
filter | process 블록만 있는 함수의 축약형, 파이프라인 요소별 처리에 특화 |
return | 그 지점에서 함수를 즉시 종료(출력 자체를 억제하지는 않음) |
예시
| |
주의사항·함정
스크립트 파일 안에서는 함수가 호출되기 전에 먼저 정의돼 있어야 한다: 대화형 세션에서는 함수를 나중에 정의해도 상관없지만, .ps1 스크립트 파일 안에서는 함수 정의가 그 함수를 호출하는 코드보다 앞에 있어야 한다. 파일 아래쪽에 정의한 함수를 파일 위쪽에서 호출하면 “인식할 수 없는 명령” 오류가 난다.
파이프라인 입력을 처리하려면 process 블록이 반드시 있어야 한다: 함수의 매개변수에 파이프라인 입력을 받도록 설정했더라도(61장에서 다룰 ValueFromPipeline), process 블록을 정의하지 않으면 파이프라인으로 여러 객체를 넘겨도 함수가 딱 한 번만 실행된다. begin/process/end 중 어떤 것도 쓰지 않으면 모든 코드가 암묵적으로 end 블록에 들어간다는 점을 기억해야 한다.
$args는 명명된 매개변수를 param()으로 선언하는 순간 함께 쓰기 까다로워진다: $args는 “선언되지 않은 나머지 인자"를 담는 배열이라, param()에 이미 매개변수를 여러 개 선언한 함수에서는 $args가 텅 비어 있거나 혼란스러운 값만 남기 쉽다. 58장에서 다룰 [CmdletBinding()]을 붙인 고급 함수에서는 $args 자체가 아예 비활성화된다.
이식성: Bash 함수(function name() { ... })는 기본적으로 위치 인자($1, $2, $@)만 지원하고 명명된 매개변수 개념이 없어, PowerShell의 param() 기반 함수보다 표현력이 제한적이다. CMD의 배치 서브루틴(:label/call :label)은 함수라는 개념 자체가 없어 %1, %2처럼 위치 인자만 훨씬 제한적으로 다룰 수 있다.
![Featured image of post [PowerShell] 57. 함수 정의와 매개변수](/post/powershell/function-parameter-definition-powershell/wordcloud_hu_eaf5e80ab6c2f3dc.webp)
![[PowerShell] 55. switch 고급 모드 — 와일드카드/정규식/파일 처리](/post/powershell/switch-wildcard-regex-file-powershell/wordcloud_hu_106a3f1b500a0d85.webp)
![[PowerShell] 56. foreach/for/while/do-while — 반복문](/post/powershell/foreach-for-while-loop-powershell/wordcloud_hu_658b84b145d1a138.webp)
![[PowerShell] 57. 함수 정의와 매개변수](/post/powershell/function-parameter-definition-powershell/wordcloud_hu_77f6f557cee7aa03.webp)
![[PowerShell] 58. [CmdletBinding()]과 고급 함수](/post/powershell/cmdletbinding-advanced-function-powershell/wordcloud_hu_bb76a800ea45ec4b.webp)
![[PowerShell] 59. 매개변수 검증(Validate 속성군)](/post/powershell/parameter-validation-attributes-powershell/wordcloud_hu_3594ab9ad8a8a99d.webp)
![[PowerShell] 61. 파이프라인 입력 매개변수(ValueFromPipeline 등)](/post/powershell/pipeline-input-parameter-powershell/wordcloud_hu_e21e024d6a200983.webp)
![[PowerShell] 26. -WhatIf/-Confirm과 ShouldProcess](/post/powershell/whatif-confirm-shouldprocess-powershell/wordcloud_hu_41a4dbb601ca47c7.webp)
![[PowerShell] 41. 변수와 데이터 타입](/post/powershell/variables-data-types-powershell/wordcloud_hu_6051f7a36d4700ee.webp)
![[PowerShell] 42. 배열과 컬렉션 기초](/post/powershell/arrays-collections-powershell/wordcloud_hu_c295cc73d4592ae5.webp)
![[PowerShell] 43. ArrayList와 Generic List(List<T>)](/post/powershell/arraylist-generic-list-powershell/wordcloud_hu_a34550a6370cee87.webp)