개발/Visual Studio Code

커맨드 팔레트 40부: VS Code 실행 중 특정 Task만 단축키로 종료하기

반응형
VS CODE 초보자 시리즈 · 커맨드 팔레트 40부

실행 중인 특정 Task를 단축키로 바로 종료하기

두 Task 중 Target만 문자열 인수로 정확히 지정해 종료하고 Guard는 계속 실행되는지 확인합니다.

단축키 뒤 Target은 Running 목록에서 사라지고 출력이 멈추며, Guard는 같은 RUN_ID로 heartbeat를 계속 출력하면 완료입니다.

매번 종료 목록에서 고르는 대신 User keybindings.json의 args 문자열로 실행 중인 Task label을 직접 지정합니다.

1. 시작하기 전에

난이도는 초급이지만 실행 중 프로세스를 끝내고 User 범위 단축키 파일을 수정하므로 위험도는 HIGH입니다. 실제 빌드·배포·감시 Task가 아닌 빈 연습 폴더에서 진행합니다.

준비할 것

  • 신뢰한 빈 연습 폴더 — 상태 표시줄에 Restricted Mode가 없고 Explorer 루트가 연습 폴더인지 확인합니다.
  • PowerShell — PowerShell에서 $PSVersionTable.PSVersion을 실행해 버전이 출력되는지 확인합니다.
  • User 단축키 백업 — Preferences: Open Keyboard Shortcuts (JSON)으로 연 파일 전체를 별도 텍스트 파일에 복사합니다.
  • 보호 대상 확인 — Tasks: Show Running Tasks에 실제 업무 Task가 있으면 실습을 중단합니다.

적용 환경 Korean beginner · Windows 11 · VS Code Stable 1.136.1 · PowerShell · User keybinding + Workspace Task

안전하게 시작하기 종료는 저장되지 않은 프로세스 상태를 잃게 할 수 있습니다. 단축키 파일 저장 직전과 종료 키 입력 직전에 Human Gate를 두고, args가 terminateAll이 아님을 확인합니다. 중단 조건: 업무 Task가 함께 실행 중이거나 예상하지 못한 Task가 종료되거나 Guard 출력이 멈추면 성공으로 판정하지 않습니다.

2. 알아둘 핵심 개념

User keybindings.json

VS Code 전체에 적용되는 사용자 단축키 규칙 파일입니다. Workspace의 .vscode/tasks.json과 범위가 다르므로 추가 객체만 제거할 수 있게 원본을 백업합니다.

명령 인수 args

단축키가 command에 전달하는 값입니다. 이 실습의 문자열은 실행 중 Task의 label 또는 identifier와 정확히 비교되므로 철자·공백·대소문자가 같아야 합니다.

직접 매칭과 Fallback

문자열이 active Task와 일치하면 선택 목록 없이 그 Task만 종료합니다. 일치하지 않으면 Select a task to terminate 목록이 나타납니다. 목록이 뜨는 것은 이번 실습의 Failure Signal입니다.

terminateAll 예약값

terminateAll은 label 매칭 전에 모든 실행 중 Task 종료 분기로 들어갑니다. Target label이나 args로 사용하지 않고 All Running Tasks도 선택하지 않습니다.

종료-only 검증

Target에 새 RUN_ID가 생기는 재시작이 아닙니다. Target 출력 정지·Running 목록 제외와 Guard의 같은 RUN_ID·진행 중 heartbeat를 동시에 확인합니다.

3. 순서대로 진행하기

각 단계의 정상 결과를 확인한 뒤 다음 단계로 이동합니다.

1. 연습 폴더와 백업 범위 확인

목적 종료 실습과 실제 작업을 분리합니다.

  1. 빈 폴더 jcos-terminate-shortcut-lab을 열고 신뢰 상태를 확인한 뒤 User keybindings.json 전체를 별도 파일에 복사합니다.

입력 위치 VS Code 상태 표시줄, Explorer, Preferences: Open Keyboard Shortcuts (JSON).

연습 폴더: <원하는-경로>\jcos-terminate-shortcut-lab
백업 파일: <백업-경로>\keybindings-before.json

두 플레이스홀더는 본인이 소유한 실제 폴더 경로로 바꿉니다.
정상 결과 현재 Workspace와 백업 사본 위치를 말할 수 있습니다.

확인 Explorer 루트가 연습 폴더이고 백업 파일에 기존 규칙이 보입니다.

실패 신호 실제 프로젝트가 열려 있거나 Restricted Mode이거나 백업이 비어 있습니다.

주의 신뢰 여부를 모르는 폴더에서 Task를 실행하지 않습니다. 되돌리기: 아무 파일도 바꾸지 말고 신뢰 가능한 새 연습 폴더로 다시 엽니다.

2. Target과 Guard Task 만들기

목적 종료 대상과 보호 대상을 동시에 관찰합니다.

  1. 연습 폴더의 .vscode/tasks.json을 만들고 아래 JSON을 그대로 저장합니다.

입력 위치 연습 Workspace의 .vscode/tasks.json.

{
  "version": "2.0.0",
  "tasks": [
    {
      "label": "JCOS Terminate Target",
      "type": "process",
      "command": "powershell.exe",
      "args": ["-NoProfile", "-Command", "$id=[guid]::NewGuid().ToString('N').Substring(0,8); Write-Output ('TERMINATE_TARGET RUN_ID=' + $id); 1..60 | ForEach-Object { Start-Sleep -Seconds 2; Write-Output ('TERMINATE_TARGET HEARTBEAT=' + $_) }"],
      "problemMatcher": [],
      "presentation": {"reveal":"always","focus":false,"panel":"dedicated","group":"jcos-terminate-shortcut","clear":true,"showReuseMessage":false}
    },
    {
      "label": "JCOS Terminate Guard",
      "type": "process",
      "command": "powershell.exe",
      "args": ["-NoProfile", "-Command", "$id=[guid]::NewGuid().ToString('N').Substring(0,8); Write-Output ('TERMINATE_GUARD RUN_ID=' + $id); 1..60 | ForEach-Object { Start-Sleep -Seconds 2; Write-Output ('TERMINATE_GUARD HEARTBEAT=' + $_) }"],
      "problemMatcher": [],
      "presentation": {"reveal":"always","focus":false,"panel":"dedicated","group":"jcos-terminate-shortcut","clear":true,"showReuseMessage":false}
    }
  ]
}
정상 결과 Problems 패널에 JSON 오류가 없고 두 label이 각각 한 번만 있습니다.

확인 type은 문자열 process, command는 powershell.exe, 실행 위치는 현재 Workspace입니다.

실패 신호 JSON 밑줄, command not found, label 중복이 보입니다.

주의 파일·네트워크는 바꾸지 않지만 종료 전까지 두 heartbeat 프로세스를 유지합니다. 되돌리기: 오류 원문을 보존하고 쉼표·따옴표·label을 고친 뒤 다시 저장합니다.

3. 후보 단축키 충돌 확인

목적 기존 동작을 덮어쓰지 않습니다.

  1. Ctrl+K Ctrl+S로 Keyboard Shortcuts를 열고 ctrl+k ctrl+alt+t를 검색한 뒤, 결과가 있으면 Show Same Keybindings로 command와 when을 확인합니다.

입력 위치 Keyboard Shortcuts 편집기 검색창.

ctrl+k ctrl+alt+t

충돌하면 이후 예시의 key만 확인한 미사용 chord로 바꿉니다.
정상 결과 같은 상황에서 먼저 실행될 활성 규칙이 없습니다.

확인 같은 key를 가진 사용자·기본·확장 규칙의 command와 when을 읽습니다.

실패 신호 같은 상황에서 실행되는 기존 규칙이 있습니다.

주의 기존 규칙을 삭제해 자리를 만들지 않습니다. 되돌리기: 변경하지 않고 다른 미사용 chord를 정합니다.

4. Target 종료 단축키 추가

목적 선택 목록 없이 실행 중 Target label을 직접 지정합니다.

  1. 백업을 확인한 뒤 Preferences: Open Keyboard Shortcuts (JSON)으로 연 기존 배열 안에 아래 객체 하나를 추가하고 저장합니다.

입력 위치 User keybindings.json. 현재 Workspace에만 한정되지 않는 User 범위입니다.

{
  "key": "ctrl+k ctrl+alt+t",
  "command": "workbench.action.tasks.terminate",
  "args": "JCOS Terminate Target"
}
정상 결과 JSON 오류가 없고 Keyboard Shortcuts 검색 결과에 사용자 규칙이 보입니다.

확인 command, 문자열 args, key를 문자 단위로 비교하고 args가 terminateAll이 아님을 확인합니다.

실패 신호 빨간 밑줄, 중복 쉼표, Target label 불일치, 예약값 terminateAll이 있습니다.

주의 저장은 모든 Workspace의 사용자 단축키에 영향을 줍니다. 되돌리기: 방금 추가한 객체만 제거하고 백업과 비교합니다.

5. 두 Task 실행과 기준값 기록

목적 종료 전 Target·Guard 상태를 고정합니다.

  1. Tasks: Run Task로 JCOS Terminate Target, 이어서 JCOS Terminate Guard를 실행합니다.

입력 위치 Command Palette와 두 전용 Terminal.

TERMINATE_TARGET RUN_ID=<8자리>
TERMINATE_GUARD RUN_ID=<8자리>

<8자리>는 실행마다 자동 생성되므로 직접 입력하지 않습니다.
정상 결과 두 Terminal이 서로 다른 RUN_ID와 증가하는 HEARTBEAT를 출력합니다.

확인 두 값을 메모하고 Tasks: Show Running Tasks에 두 데모 label만 있는지 확인합니다.

실패 신호 업무 Task가 함께 보이거나 하나만 실행 중이거나 PowerShell 오류가 납니다.

주의 업무 Task가 Running 목록에 있으면 종료 단축키를 누르지 않습니다. 되돌리기: 데모 label만 각각 종료하고 Step 2를 고친 뒤 다시 실행합니다.

6. Human Gate 뒤 Target만 종료

목적 문자열 args의 직접 매칭과 종료 범위를 관찰합니다.

  1. Running 목록에 두 데모만 있고 args가 정확함을 다시 확인한 뒤 Ctrl+K를 놓고 Ctrl+Alt+T를 누릅니다.

입력 위치 VS Code 창. 예시에는 when이 없어 전역으로 활성화됩니다.

단축키 뒤 기대 상태:
- Target: HEARTBEAT 증가 중지, Running 목록에서 사라짐
- Guard:  같은 RUN_ID, HEARTBEAT 계속 증가
정상 결과 선택 목록 없이 Target만 종료되고 자동 재시작되지 않습니다.

확인 Target 출력 정지, Running 목록의 Guard 1개, Guard RUN_ID 유지와 heartbeat 증가를 함께 비교합니다.

실패 신호 선택 목록이 뜨거나 Guard가 종료되거나 Target에 새 RUN_ID가 생깁니다.

주의 종료는 Target 프로세스 상태를 잃게 합니다. 되돌리기: 선택 목록은 Esc로 취소합니다. 오종료가 있으면 단축키 객체를 제거하고 데모만 다시 실행합니다.

7. 충돌 로그와 종료-only 상태 교차 확인

목적 의도한 command가 실행됐고 재시작되지 않았는지 입력 화면과 독립적으로 확인합니다.

  1. 필요하면 Developer: Toggle Keyboard Shortcuts Troubleshooting을 켭니다. Target을 다시 실행해 같은 RUN_ID 기준을 잡고 chord를 한 번 누른 뒤 즉시 로그 기능을 끕니다.

입력 위치 Command Palette, Output 패널의 Keyboard Shortcuts Troubleshooting 로그, Running Tasks.

기대 command ID:
workbench.action.tasks.terminate

금지된 args:
terminateAll
정상 결과 로그에 의도한 command가 기록되고 Target만 다시 사라지며 Guard는 같은 RUN_ID로 유지됩니다.

확인 로그, Running 목록, 두 Terminal을 교차 확인합니다.

실패 신호 다른 command가 선택되거나 Target이 재시작되거나 두 Task가 함께 종료됩니다.

주의 로그 원문을 보존하고 원인을 추정하지 않습니다. 되돌리기: 단축키 객체를 제거하고 Step 3에서 다른 chord를 정합니다.

8. Guard 종료와 사용자 단축키 복원

목적 장기 실행 프로세스와 전역 사용자 변경을 남기지 않습니다.

  1. Tasks: Terminate Task에서 JCOS Terminate Guard만 선택하고, User keybindings.json에서 추가한 객체만 제거합니다.

입력 위치 Command Palette, Terminal, User keybindings.json.

정리 후 기대 상태:
- Tasks: Show Running Tasks → 데모 0개
- Keyboard Shortcuts 검색 → 추가 사용자 규칙 0개
- 백업과 현재 keybindings.json → 기존 규칙 동일
정상 결과 데모 Task와 추가 단축키가 모두 사라지고 기존 사용자 규칙은 보존됩니다.

확인 Running 목록과 백업 비교를 수행합니다.

실패 신호 데모가 남거나 다른 사용자 규칙까지 달라졌습니다.

주의 All Running Tasks는 실제 업무 Task까지 끝낼 수 있습니다. 되돌리기: Guard label만 종료하고 백업에서 원래 사용자 배열을 복원합니다. 원인 UNKNOWN이면 더 수정하지 않습니다.

4. 완료 확인하기

입력 화면과 독립된 방법을 포함해 결과를 교차 확인합니다.

  • Target heartbeat와 Running 목록을 비교합니다 — 출력 증가가 멈추고 Target이 목록에서 사라집니다.
  • Guard의 전후 RUN_ID와 heartbeat를 비교합니다 — RUN_ID는 같고 heartbeat는 계속 증가합니다.
  • Keyboard Shortcuts Troubleshooting 로그를 확인합니다 — workbench.action.tasks.terminate가 선택됩니다.
  • Target Terminal을 다시 확인합니다 — 새 RUN_ID가 생기지 않아 종료-only 상태입니다.
  • 정리 뒤 Running Tasks와 사용자 규칙을 확인합니다 — 데모 0개, 추가 규칙 0개입니다.
완료 기준 문자열 인수가 Target만 직접 종료했고 Guard와 기존 사용자 단축키는 보존됐습니다.

5. 문제가 생겼다면

Select a task to terminate가 나타남

먼저 확인 args가 정확히 JCOS Terminate Target인지, Target이 실제 실행 중인지 확인합니다.

복구 Esc로 목록을 취소하고 label을 고칩니다. 임의 선택으로 성공을 우회하지 않습니다.

재합류 VSC-STEP-05

두 Task가 모두 종료됨

먼저 확인 args가 terminateAll인지, All Running Tasks를 선택했는지, 실제 command가 맞는지 로그를 확인합니다.

복구 단축키 객체를 제거하고 필요한 데모만 다시 실행한 뒤 정확한 Target label로 복원합니다.

재합류 VSC-STEP-04

Guard만 종료됨

먼저 확인 args가 Guard label로 바뀌지 않았는지 확인합니다.

복구 Guard를 다시 실행하고 args를 Target label로 고친 뒤 기준값을 다시 기록합니다.

재합류 VSC-STEP-05

아무 반응이 없거나 다른 command가 실행됨

먼저 확인 Keyboard Shortcuts Troubleshooting 로그와 같은 key의 사용자·기본·확장 규칙을 확인합니다.

복구 충돌 없는 chord를 선택하고 예시의 key만 바꿉니다.

재합류 VSC-STEP-03

Failed to terminate running task 또는 ProcessNotFound

먼저 확인 오류 원문, Target Terminal 마지막 출력, Running 목록을 보존합니다. 원인을 권한이나 자식 프로세스로 단정하지 않습니다.

복구 이미 끝났다면 Guard만 정리합니다. 여전히 실행 중이면 UI의 Tasks: Terminate Task에서 Target만 한 번 선택하고, 실패가 반복되면 원인 UNKNOWN으로 중단합니다.

재합류 VSC-STEP-08

핵심 판단 원인을 확인하지 못하면 상태와 Evidence를 보존하고 임의 변경 없이 중단합니다.

6. 핵심 정리와 공식 자료

  • User keybindings.json의 문자열 args로 실행 중인 특정 Task label을 지정할 수 있습니다.
  • 정확히 일치하면 그 Task만 종료하고, 불일치하면 선택 목록으로 돌아갑니다.
  • terminateAll은 모든 실행 중 Task를 종료하는 예약값이므로 Target 인수로 쓰지 않습니다.
  • Target 정지와 Guard의 같은 RUN_ID·진행 중 heartbeat를 함께 확인해야 보호가 증명됩니다.
  • 백업, 충돌 검사, Human Gate, 정리와 롤백까지 마쳐야 완료입니다.

공식 자료

아래 자료는 2026-09-08 Asia/Seoul에 접근했습니다. 문서 웹 페이지는 현재 Stable을 설명하고, 소스 링크는 검증한 Stable commit에 고정했습니다. 실제 단축키 충돌과 한국어 UI 번역은 설치 환경에 따라 달라 독자가 확인해야 합니다.

다음 편 예고 커맨드 팔레트 41부에서는 User keybindings.json의 when: "taskRunning"으로 실행 중일 때만 종료 단축키를 활성화하고 Context Key·충돌·롤백을 확인합니다.
반응형
이 글이 유용했다면 링크를 공유해 보세요.