개요
Start-Job은 명령을 현재 세션과 분리된 별도 프로세스에서 백그라운드로 실행하는 cmdlet이다. 지금까지 배운 명령은 모두 실행이 끝날 때까지 콘솔을 붙잡고 있었는데, Start-Job은 오래 걸리는 작업을 뒤로 보내 놓고 그동안 다른 작업을 계속할 수 있게 해 준다. 79장에서 다룰 ForEach-Object -Parallel과 함께 PowerShell의 병렬·비동기 실행 모델을 이루는 두 축 중 하나다.
정신 모델은 “Start-Job은 작업을 시작하고 즉시 작업 정보만 돌려주는 접수증이고, 그 작업이 실제로 만들어낸 결과는 Receive-Job으로 나중에 따로 찾으러 가야 한다"는 것이다.
사용법
| |
종류
| cmdlet | 역할 |
|---|---|
Start-Job | 백그라운드 작업 시작, 즉시 작업 객체 반환(결과 아님) |
Get-Job | 실행 중인·완료된 작업의 상태(State) 조회 |
Receive-Job | 작업이 만든 출력을 가져옴(기본적으로 한 번 가져오면 비워짐, -Keep으로 유지) |
Wait-Job | 작업이 끝날 때까지 대기(스크립트를 동기적으로 만들고 싶을 때) |
Stop-Job / Remove-Job | 실행 중인 작업 중단 / 작업 객체 자체를 정리 |
&(백그라운드 연산자) | PowerShell 6+, Start-Job과 거의 동일한 효과를 내는 단축 문법 |
예시
| |
주의사항·함정
작업 스크립트 블록은 완전히 별도의 프로세스에서 실행되어, 현재 세션의 함수·변수를 자동으로 볼 수 없다: Start-Job -ScriptBlock { MyFunction }처럼 세션에서 정의한 함수를 그대로 부르면 “명령을 찾을 수 없다"는 오류가 난다. -InitializationScript로 필요한 모듈·함수를 먼저 로드하거나, -ArgumentList로 필요한 값만 명시적으로 전달해야 한다 — 63장의 클로저와 달리 잡(Job)은 부모 세션의 상태를 자동으로 물려받지 않는다.
Receive-Job은 기본적으로 결과를 한 번 가져오면 비워 버린다: -Keep을 붙이지 않으면 같은 작업에 Receive-Job을 두 번 호출했을 때 두 번째는 빈 결과만 나온다. 결과를 여러 번 참조해야 한다면 -Keep을 쓰거나, 처음 받은 결과를 변수에 저장해 둬야 한다.
작업이 많아지면 프로세스 생성 오버헤드가 누적된다: Start-Job은 매번 별도의 pwsh 프로세스를 새로 띄우기 때문에, 아주 짧은 작업을 수백 개 병렬로 돌리기에는 79장의 ForEach-Object -Parallel(스레드 기반)이나 Start-ThreadJob이 훨씬 가볍다. Start-Job은 작업 하나하나가 상당히 무겁고 오래 걸리는 경우(파일 처리, 네트워크 대기 등)에 적합하다.
세션을 닫으면 실행 중이던 작업 정보도 함께 사라진다: 잡은 현재 세션에 종속되므로, 콘솔을 닫으면 미처 Receive-Job으로 수거하지 못한 결과는 잃어버린다. 장시간 실행되는 배치 작업이라면 예약 작업(78장이 아니라 12부에서 다룰 스케줄러)이나 결과를 파일로 저장하는 방식을 함께 고려해야 한다.
이식성: Bash의 &(백그라운드 실행)와 jobs/wait 명령이 개념적으로 가장 가깝다 — PowerShell 6+의 & 백그라운드 연산자도 이름과 동작이 유사하게 설계됐다. 다만 Bash의 백그라운드 작업은 같은 셸 프로세스 안의 서브프로세스인 반면, PowerShell의 Start-Job은 완전히 독립된 pwsh 프로세스를 새로 띄운다는 점이 격리 수준에서 다르다. CMD의 start 명령도 새 창에서 명령을 실행하지만, 구조화된 결과 수집(Receive-Job에 대응하는 개념)은 없다.
![Featured image of post [PowerShell] 78. Start-Job/Get-Job/Receive-Job — 백그라운드 작업](/post/powershell/start-job-get-job-receive-job-powershell/wordcloud_hu_50becffd822a0db8.webp)
![[PowerShell] 76. PowerShell Gallery — Install-Module/Find-Module](/post/powershell/powershell-gallery-install-find-module-powershell/wordcloud_hu_68568dc7c4947f25.webp)
![[PowerShell] 77. PowerShell 클래스(class 키워드)](/post/powershell/powershell-class-keyword-powershell/wordcloud_hu_5ff5e6ec1d4f4d49.webp)
![[PowerShell] 78. Start-Job/Get-Job/Receive-Job — 백그라운드 작업](/post/powershell/start-job-get-job-receive-job-powershell/wordcloud_hu_f975cbd44945c564.webp)
![[PowerShell] 79. ForEach-Object -Parallel(PowerShell 7+)](/post/powershell/foreach-object-parallel-threadjob-powershell/wordcloud_hu_30c9034b5b05c027.webp)
![[PowerShell] 80. PackageManagement — Get-Package/Install-Package](/post/powershell/packagemanagement-get-install-package-powershell/wordcloud_hu_a30d460874a4540e.webp)
![[PowerShell] 74. 모듈 개념과 구조(.psm1/.psd1)](/post/powershell/module-structure-psm1-psd1-powershell/wordcloud_hu_7fca0b454a750e2a.webp)
![[PowerShell] 75. Import-Module/Get-Module/Remove-Module](/post/powershell/import-get-remove-module-powershell/wordcloud_hu_f7c6ed2cf0491565.webp)