윈도우 PATH 환경 변수 설정법: '내부 또는 외부 명령, 실행할 수 있는 프로그램, 또는 배치 파일이 아닙니다' 해결
이 글의 핵심
프로그램을 설치했는데 cmd에서 '내부 또는 외부 명령이 아닙니다', PowerShell에서 'is not recognized'가 뜬다면 거의 항상 PATH 문제입니다. 이 글은 윈도우가 명령을 찾는 순서, 사용자 변수와 시스템 변수가 합쳐지는 방식, GUI로 안전하게 추가하는 법, 열려 있던 터미널과 VS Code가 변경을 못 보는 이유, setx를 쓰면 안 되는 이유, python을 치면 Microsoft Store가 열리는 현상, 버전 두 개가 충돌할 때 순서 정리까지 다룹니다.
이런 오류가 나왔다면 PATH 문제입니다
Python, Node.js, FFmpeg, Git 같은 프로그램을 설치한 뒤 터미널에서 이름을 쳤는데 아래와 같은 메시지가 나오는 경우가 있습니다. 한국어 윈도우의 명령 프롬프트(cmd)에서는 이렇게 나옵니다.
'python'은(는) 내부 또는 외부 명령, 실행할 수 있는 프로그램, 또는
배치 파일이 아닙니다.
영어 윈도우의 cmd에서는 이렇게 나옵니다.
'python' is not recognized as an internal or external command,
operable program or batch file.
Windows PowerShell 5.1에서는 다음과 같은 오류가 붉은 글씨로 나옵니다.
python : The term 'python' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
한국어 PowerShell에서는 같은 오류가 이렇게 번역되어 나옵니다.
'python' 용어가 cmdlet, 함수, 스크립트 파일 또는 실행할 수 있는 프로그램 이름으로 인식되지 않습니다. 이름이 정확한지 확인하고 경로가 포함된 경우 경로가 올바른지 검증한 다음 다시 시도하십시오.
PowerShell 7(pwsh)에서는 문장이 조금 짧아져 The term 'python' is not recognized as a name of a cmdlet, function, script file, or executable program.으로 나옵니다.
세 메시지는 모두 같은 뜻입니다. “그 이름의 실행 파일을 내가 찾아보는 폴더 어디에서도 못 찾았다”는 것입니다. 프로그램이 설치되지 않았다는 뜻이 아닙니다. 설치는 되어 있는데 터미널이 그 위치를 모르는 경우가 대부분이고, 그 “찾아보는 폴더 목록”이 바로 PATH 환경 변수입니다.
이 글의 기준 환경은 윈도우 11 23H2/24H2와 윈도우 10 22H2이며, 기본 cmd, Windows PowerShell 5.1, PowerShell 7을 모두 다룹니다. 화면 메뉴 이름은 한국어 윈도우 기준입니다.
PATH가 하는 일과 명령을 찾는 순서
PATH는 세미콜론(;)으로 구분한 폴더 목록입니다. 터미널에 python처럼 경로 없이 이름만 치면, 셸은 이 목록의 폴더를 왼쪽부터 차례로 열어 보며 python.exe가 있는지 확인하고, 처음 발견한 것을 실행합니다. 끝까지 못 찾으면 위의 오류를 냅니다.
cmd의 탐색 순서는 다음과 같습니다.
dir,cd,set같은 cmd 내장 명령인지 확인합니다.- 현재 폴더에서 찾습니다.
- PATH의 폴더를 왼쪽부터 순서대로 찾습니다.
각 폴더에서는 이름 뒤에 PATHEXT 환경 변수에 적힌 확장자(.COM;.EXE;.BAT;.CMD;...)를 하나씩 붙여 봅니다. 그래서 python만 쳐도 python.exe가 실행되고, npm만 쳐도 npm.cmd가 실행됩니다. 드물게 PATHEXT가 망가져서 PATH가 멀쩡한데도 모든 외부 명령이 안 되는 경우가 있는데, echo %PATHEXT%로 값이 비어 있지 않은지 확인하면 됩니다.
PowerShell은 두 가지가 다릅니다. 하나는 별칭(alias), 함수, cmdlet을 외부 실행 파일보다 먼저 찾는다는 점입니다. PowerShell에서 where를 치면 where.exe가 아니라 Where-Object의 별칭이 실행되는 이유가 이것입니다. 다른 하나는 보안상의 이유로 현재 폴더를 탐색하지 않는다는 점입니다. 현재 폴더에 ffmpeg.exe가 있어도 ffmpeg만 치면 못 찾고, 아래와 같은 안내가 함께 나옵니다.
Suggestion [3,General]: The command ffmpeg was not found, but does exist in the current location. Windows PowerShell does not load commands from the current location by default. If you trust this command, instead type: ".\ffmpeg". See "get-help about_Command_Precedence" for more details.
이 경우는 PATH를 고칠 일이 아니라 .\ffmpeg처럼 현재 폴더를 명시하면 됩니다. cmd에서는 되는데 PowerShell에서만 안 된다면 이 차이를 먼저 의심해 보세요.
지금 PATH에 무엇이 들어 있는지 확인하기
무작정 PATH를 고치기 전에, 현재 셸이 보고 있는 PATH와 명령이 실제로 어디서 실행되는지를 먼저 확인하는 것이 좋습니다. 원인이 “PATH에 없음”이 아니라 “다른 버전이 먼저 잡힘”인 경우도 많기 때문입니다.
cmd에서는 다음 명령을 씁니다.
:: PATH 전체를 한 줄로 출력
echo %PATH%
:: 같은 내용을 "PATH=" 형식으로 출력
path
:: python이라는 이름이 PATH 어디에서 발견되는지 모두 출력 (위에 있는 것이 실행됨)
where python
PowerShell에서는 다음 명령을 씁니다.
# PATH를 한 줄에 폴더 하나씩 보기 좋게 출력
$env:Path -split ';'
# PowerShell이 실제로 무엇을 실행할지 확인 (별칭·함수까지 포함)
Get-Command python
# 같은 이름의 후보를 모두 출력
Get-Command python -All
# where.exe를 쓰려면 반드시 .exe까지 붙여야 함 (where는 Where-Object 별칭)
where.exe python
where python이 INFO: Could not find files for the given pattern(s).을 출력한다면 그 이름의 실행 파일이 PATH 어디에도 없다는 뜻이므로, 아래 방법으로 폴더를 추가하면 됩니다. 반대로 결과가 여러 줄 나온다면 맨 위 줄이 실제로 실행되는 파일이므로, 원하는 버전이 아닌 경우 순서를 정리해야 합니다.
사용자 변수와 시스템 변수는 어떻게 합쳐지는가
환경 변수 창을 열면 위쪽에 “사용자 변수”, 아래쪽에 “시스템 변수”가 있고, 두 곳 모두에 Path가 있습니다. 둘 중 어디에 넣어야 하는지 헷갈리는 경우가 많은데, 동작을 알면 선택이 쉬워집니다.
| 구분 | 레지스트리 위치 | 적용 대상 | 수정 권한 |
|---|---|---|---|
| 시스템 변수 | HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment | 이 PC의 모든 사용자 | 관리자 |
| 사용자 변수 | HKCU\Environment | 현재 로그인한 사용자 | 본인 |
새 프로세스가 받는 최종 PATH는 시스템 Path 뒤에 사용자 Path를 이어 붙인 값입니다. Path가 아닌 일반 변수는 같은 이름이 양쪽에 있으면 사용자 쪽이 덮어쓰지만, Path만은 예외적으로 덮어쓰지 않고 합칩니다.
이 순서에서 중요한 결론이 하나 나옵니다. 같은 이름의 실행 파일이 시스템 Path와 사용자 Path 양쪽에 있으면 항상 시스템 Path 쪽이 이깁니다. 사용자 Path 맨 위로 아무리 올려도 시스템 Path에 있는 다른 버전을 이길 수 없습니다. 버전 충돌을 정리할 때 이 점을 모르면 시간을 많이 쓰게 됩니다.
선택 기준은 이렇게 잡으면 됩니다.
- 혼자 쓰는 PC에서 개발 도구를 추가할 때는 사용자 변수 Path가 무난합니다. 관리자 권한이 필요 없고, 잘못 넣어도 다른 계정이나 시스템 서비스에 영향을 주지 않습니다.
- 모든 사용자, Windows 서비스, 작업 스케줄러에서 다른 계정으로 실행하는 작업이 그 명령을 써야 한다면 시스템 변수 Path에 넣습니다.
- 시스템 Path에 이미 다른 버전이 들어 있고 그것을 이기고 싶다면, 사용자 Path가 아니라 시스템 Path 안에서 순서를 바꾸거나 기존 항목을 제거해야 합니다.
GUI로 PATH에 폴더 추가하기
가장 안전한 방법은 윈도우가 제공하는 환경 변수 편집 창을 쓰는 것입니다. 이 창은 값을 레지스트리에 저장한 뒤 “환경이 바뀌었다”는 알림(WM_SETTINGCHANGE 메시지)을 다른 프로그램에 보내 주기 때문에, 이후 새로 실행하는 프로그램이 바로 새 값을 받습니다.
환경 변수 창 여는 법
다음 중 편한 방법을 쓰면 됩니다.
- 시작 메뉴 검색: 시작 버튼을 누르고 “시스템 환경 변수 편집”을 입력해 엽니다. 영어 윈도우에서는 “Edit the system environment variables”입니다. 사용자 변수만 고칠 거라면 “계정의 환경 변수 편집”을 열어도 됩니다. 이쪽은 관리자 권한을 묻지 않습니다.
- 실행 창: Win+R을 누르고
sysdm.cpl을 입력하면 시스템 속성 창이 열립니다. 고급 탭 → 환경 변수 버튼을 누릅니다. - 설정 앱: 윈도우 11에서는 설정 → 시스템 → 정보 → “고급 시스템 설정”을 누르면 같은 시스템 속성 창이 열립니다.
추가하는 순서
- 사용자 변수(또는 시스템 변수) 목록에서
Path를 선택하고 편집을 누릅니다. - 목록 형태의 편집 창이 뜨면 새로 만들기를 누르고 폴더 경로를 붙여 넣습니다.
- 위로 이동/아래로 이동으로 순서를 정할 수 있습니다. 위에 있을수록 먼저 탐색됩니다.
- 편집 창, 환경 변수 창, 시스템 속성 창을 모두 확인으로 닫습니다. 오른쪽 위 X로 닫으면 저장되지 않습니다.
경로를 정확히 복사하려면 탐색기에서 실행 파일이 들어 있는 폴더를 연 다음, 주소 표시줄을 클릭하면 나오는 텍스트를 그대로 복사하는 것이 가장 실수가 적습니다.
실행 파일이 아니라 그 파일이 들어 있는 폴더를 넣어야 합니다
가장 흔한 실수가 PATH에 C:\ffmpeg\bin\ffmpeg.exe처럼 실행 파일 경로 자체를 넣는 것입니다. PATH의 각 항목은 “이 폴더 안을 찾아보라”는 뜻이므로, 파일 경로를 넣으면 윈도우는 ffmpeg.exe라는 이름의 폴더를 찾다가 실패하고 결국 명령을 못 찾습니다. 넣어야 할 것은 C:\ffmpeg\bin입니다.
비슷한 실수로, 압축을 푼 최상위 폴더(C:\ffmpeg)를 넣는 경우도 있습니다. 많은 도구가 실행 파일을 bin 하위 폴더에 두기 때문에, 반드시 .exe가 실제로 들어 있는 폴더인지 확인해야 합니다. PATH는 하위 폴더까지 뒤지지 않습니다.
경로에 공백이 있어도 따옴표는 넣지 않습니다
C:\Program Files\nodejs\처럼 공백이 있는 경로도 PATH에는 따옴표 없이 그대로 넣습니다. PATH는 공백이 아니라 세미콜론으로 항목을 구분하므로 공백은 문제가 되지 않습니다. 오히려 "C:\Program Files\nodejs"처럼 따옴표를 넣으면 cmd는 대체로 처리하지만, 따옴표를 경로의 일부로 읽는 프로그램이 있어서 특정 도구에서만 명령을 못 찾는 이상한 증상이 생길 수 있습니다. 끝에 \를 붙이든 안 붙이든 동작은 같습니다.
고쳤는데도 안 될 때: 열려 있던 창은 옛날 PATH를 들고 있다
PATH를 고친 직후 가장 많이 듣는 질문이 “분명히 추가했는데 여전히 안 된다”입니다. 대부분은 설정이 틀린 것이 아니라 이미 열려 있던 터미널에 새 값이 반영되지 않은 것입니다.
윈도우에서 환경 변수는 프로세스가 시작될 때 부모 프로세스로부터 복사됩니다. 시작 메뉴나 바탕 화면에서 실행한 프로그램은 탐색기(explorer.exe)의 환경을 물려받는데, 탐색기는 환경 변수 창이 보내는 변경 알림을 받고 자기 환경을 새 값으로 갱신합니다. 그래서 PATH를 바꾼 뒤 시작 메뉴에서 새로 연 터미널은 새 값을 받습니다.
반면 이미 실행 중인 프로세스는 시작할 때 복사한 값을 계속 씁니다. 다음 경우가 대표적입니다.
- PATH를 바꾸기 전에 열어 둔 cmd, PowerShell 창은 닫고 새로 열어야 합니다.
- VS Code의 통합 터미널은 VS Code 프로세스의 환경을 물려받습니다. 터미널 탭만 새로 여는 것으로는 부족하고, VS Code 창을 모두 닫고 다시 실행해야 합니다. 특히 다른 터미널에서
code .로 VS Code를 띄웠다면 그 터미널의 옛날 환경을 물려받으므로, 시작 메뉴에서 VS Code를 실행하는 편이 확실합니다. 확장이 컴파일러를 못 찾는 문제는 VS Code C++ 개발 환경 설정에서도 같은 원인으로 자주 나옵니다. - IntelliJ, Android Studio 같은 IDE, 그리고 IDE가 띄운 빌드 도구도 마찬가지로 IDE를 완전히 재시작해야 합니다.
- Windows Terminal은 최근 버전에서 새 탭을 열 때 환경 변수를 다시 읽도록 바뀌었지만, 버전과 설정에 따라 다를 수 있으므로 창을 완전히 닫고 다시 여는 것이 가장 확실합니다.
재부팅이나 로그아웃까지 할 필요는 보통 없습니다. 다만 레지스트리를 직접 수정하는 등 변경 알림이 가지 않는 방법으로 고쳤다면, 탐색기가 새 값을 모르기 때문에 로그아웃 후 다시 로그인해야 반영됩니다.
지금 열린 PowerShell 창을 닫지 않고 새 PATH를 쓰고 싶다면, 레지스트리에 저장된 값을 다시 읽어 현재 세션에 넣을 수 있습니다.
# 저장된 시스템 Path + 사용자 Path를 다시 읽어 현재 세션에 적용
$env:Path = [Environment]::GetEnvironmentVariable('Path', 'Machine') + ';' +
[Environment]::GetEnvironmentVariable('Path', 'User')
cmd에서 지금 창에만 임시로 추가하려면 set PATH=%PATH%;C:\ffmpeg\bin을 씁니다. 이 값은 창을 닫으면 사라지고 다른 창에도 영향을 주지 않으므로, 설정을 영구히 바꾸기 전에 경로가 맞는지 시험해 볼 때 유용합니다.
setx로 PATH를 고치면 안 되는 이유
인터넷 검색을 하면 아래 명령으로 PATH를 추가하라는 안내가 자주 나옵니다.
setx PATH "%PATH%;C:\ffmpeg\bin"
이 명령은 PATH를 망가뜨리는 원인으로 유명합니다. 기존 PATH가 길다면 이 명령은 실행하지 마세요. 문제가 세 가지 있습니다.
첫째, setx는 값을 1024자에서 잘라 저장합니다. 개발 도구를 여러 개 설치한 PC는 PATH가 1024자를 쉽게 넘기 때문에, 뒷부분 항목이 통째로 사라집니다. 이때 아래 경고가 나오지만 이미 저장된 뒤입니다.
WARNING: The data being saved is truncated to 1024 characters.
둘째, %PATH%는 현재 창의 PATH, 즉 시스템 Path와 사용자 Path를 합친 값입니다. 이것을 setx PATH로 저장하면 사용자 Path에 시스템 Path 내용까지 통째로 복사됩니다. 그 결과 같은 항목이 두 번씩 들어가고, 나중에 시스템 Path를 정리해도 사용자 Path에 남은 복사본 때문에 옛날 항목이 계속 살아 있게 됩니다.
셋째, %JAVA_HOME%\bin처럼 다른 변수를 참조하던 항목이 그 시점의 실제 경로로 풀려서 저장됩니다. JAVA_HOME을 나중에 바꿔도 PATH는 옛날 경로를 계속 가리킵니다.
이미 setx로 PATH를 덮어써 버렸다면, 사용자 Path를 열어 시스템 Path와 중복된 항목을 지우고 잘린 항목을 다시 추가해야 합니다. 원래 값을 정확히 알기 어려우므로, 아래 “되돌리는 법”에서 설명하는 백업을 평소에 해 두는 것이 가장 좋은 대비책입니다. setx는 PATH가 아닌 짧은 일반 변수를 설정할 때는 써도 괜찮습니다.
PowerShell로 PATH를 안전하게 추가하기
스크립트로 여러 PC에 같은 설정을 넣어야 할 때는 GUI 대신 .NET의 [Environment]::SetEnvironmentVariable을 쓸 수 있습니다. 핵심은 현재 창의 $env:Path가 아니라 저장된 사용자 Path만 읽어서 거기에 덧붙이는 것입니다. 그래야 setx의 두 번째 문제(시스템 Path 복사)가 생기지 않습니다. 길이 제한도 1024자가 아닙니다.
$newDir = 'C:\ffmpeg\bin'
# 저장된 "사용자" Path만 읽음 ($env:Path를 쓰면 시스템 Path까지 섞임)
$userPath = [Environment]::GetEnvironmentVariable('Path', 'User')
# 이미 들어 있으면 다시 넣지 않음 (끝의 \ 유무 차이는 무시)
$entries = $userPath -split ';' | Where-Object { $_ -ne '' }
if ($entries.TrimEnd('\') -notcontains $newDir.TrimEnd('\')) {
$entries += $newDir
[Environment]::SetEnvironmentVariable('Path', ($entries -join ';'), 'User')
Write-Host "추가했습니다: $newDir"
} else {
Write-Host "이미 있습니다: $newDir"
}
이 방법도 GUI처럼 변경 알림을 보내므로, 이후 시작 메뉴에서 새로 연 터미널에 반영됩니다. 실행한 현재 창에는 반영되지 않으니 위에서 설명한 세션 갱신 명령을 함께 쓰거나 창을 새로 여세요. 시스템 Path를 고치려면 'User' 대신 'Machine'을 쓰고, PowerShell을 관리자 권한으로 실행해야 합니다.
한 가지 주의할 점이 있습니다. GetEnvironmentVariable은 %JAVA_HOME%\bin 같은 참조를 실제 경로로 풀어서 돌려주고, SetEnvironmentVariable은 값을 변수 확장을 하지 않는 형식으로 저장하는 것으로 알려져 있습니다. 그래서 PATH에 %변수% 형태의 항목이 있다면 이 스크립트를 돌린 뒤 그 항목이 고정된 경로로 바뀔 수 있습니다. PATH에 변수 참조를 쓰고 있다면 GUI로 편집하는 편이 안전합니다.
python을 치면 Microsoft Store가 열릴 때: 앱 실행 별칭
윈도우 10/11에서 Python을 설치하지 않은 상태, 혹은 설치했는데 PATH가 제대로 잡히지 않은 상태에서 python을 치면 Microsoft Store의 Python 페이지가 열리거나 아래 메시지가 나옵니다.
Python was not found; run without arguments to install from the Microsoft Store, or disable this shortcut from Settings > Manage App Execution Aliases.
이것은 오류가 아니라 윈도우의 “앱 실행 별칭” 기능입니다. 사용자 Path에 기본으로 들어 있는 %LOCALAPPDATA%\Microsoft\WindowsApps 폴더에 python.exe, python3.exe라는 이름의 바로 가기가 들어 있고, 진짜 Python을 찾기 전에 이것이 먼저 잡히면 Store로 안내하는 것입니다. where python을 쳐서 WindowsApps 경로가 맨 위에 나온다면 이 경우입니다.
python.org에서 받은 Python을 쓸 생각이라면 별칭을 끄는 것이 깔끔합니다.
- 윈도우 11: 설정 → 앱 → 고급 앱 설정 → 앱 실행 별칭
- 윈도우 10: 설정 → 앱 → 앱 및 기능 → 앱 실행 별칭
목록에서 “앱 설치 관리자 python.exe”, “앱 설치 관리자 python3.exe” 두 항목을 끕니다. 그다음 새 터미널에서 where python을 다시 실행해 python.org Python 경로가 나오는지 확인합니다. 아무것도 안 나온다면 설치할 때 “Add python.exe to PATH”를 체크하지 않은 것이므로, 아래 예시의 Python 폴더 두 개를 직접 추가하거나 설치 프로그램을 다시 실행해 Modify로 이 옵션을 켜면 됩니다. Python 설치 자체는 Python 개발 환경 설정에서 자세히 다룹니다.
python.org 설치 프로그램은 py라는 런처도 함께 설치합니다. 런처는 C:\Windows에 설치되는 경우가 많아 PATH 설정과 상관없이 동작하고, py -3.12처럼 버전을 골라 실행할 수 있습니다. PATH 순서 때문에 버전이 계속 꼬인다면 python 대신 py를 쓰는 것도 좋은 방법입니다.
같은 프로그램이 두 개 설치되어 있을 때: 순서 충돌
Python 3.11과 3.12, JDK 17과 21처럼 같은 프로그램의 버전이 둘 이상 설치되어 있으면, 명령을 찾지 못하는 대신 원하지 않는 버전이 실행되는 문제가 생깁니다. python --version이 예상과 다른 버전을 출력하거나, pip install로 설치한 패키지를 python에서 import하지 못하는 증상이 대표적입니다. 이 경우 pip와 python이 서로 다른 설치본에서 실행되고 있을 가능성이 높습니다.
진단은 where로 합니다.
where python
where pip
where java
여러 줄이 나오면 맨 위가 실행되는 파일입니다. 이 글을 쓰면서 작업용 윈도우 11 PC에서 실행해 보니 실제로 세 줄이 나왔습니다.
PS> where.exe python
C:\Users\<사용자>\AppData\Local\Programs\Python\Python311\python.exe
C:\Users\<사용자>\AppData\Local\Programs\Python\Python313\python.exe
C:\Users\<사용자>\AppData\Local\Microsoft\WindowsApps\python.exe
PS> python --version
Python 3.11.4
더 최신인 3.13이 있는데도 3.11이 실행됩니다. 사용자 변수와 시스템 변수를 따로 꺼내 보면 이유가 보입니다.
[Environment]::GetEnvironmentVariable('Path', 'Machine') -split ';' | Select-String Python
[Environment]::GetEnvironmentVariable('Path', 'User') -split ';' | Select-String Python
이 PC에서는 Python311과 Python311\Scripts가 시스템 Path에, Python313과 Python313\Scripts가 사용자 Path에 들어 있었습니다. 앞에서 설명한 대로 시스템 Path가 먼저 붙기 때문에, 사용자 Path 편집 창에서 3.13을 아무리 맨 위로 올려도 3.11이 이깁니다. pip도 같은 이유로 3.11의 Scripts 폴더에서 실행되므로, pip install로 설치한 패키지가 3.13에서는 안 보이는 증상이 생깁니다. 맨 아래의 WindowsApps\python.exe는 뒤에서 설명할 앱 실행 별칭입니다. 진짜 Python이 앞에 있어서 여기서는 영향이 없습니다. 이 PC의 Path에는 항목이 62개나 되어서, 눈으로 훑어서는 이런 순서 문제를 찾기 어렵습니다. where.exe와 위 두 줄로 확인하는 편이 빠릅니다.
버전을 명시해서 실행해야 한다면 Python 설치 프로그램이 함께 넣어 주는 py 런처가 편합니다. py는 C:\Windows\py.exe에 설치되어 Path 순서와 상관없이 동작합니다. 같은 PC에서 py --list를 실행하면 아래처럼 나옵니다. * 표시는 py만 쳤을 때의 기본 버전입니다. 그래서 이 PC에서는 python은 3.11, py는 3.13이라는 엇갈린 상태가 됩니다.
PS> py --list
-V:3.13 * Python 3.13 (64-bit)
-V:3.11 Python 3.11 (64-bit)
-V:3.9 Python 3.9 (64-bit)
py -3.13 -m pip install ...처럼 버전을 지정하면 어느 Python에 설치할지 헷갈릴 일이 없습니다.
원하는 버전이 맨 위가 아니라면 다음 중 하나로 정리합니다.
- 쓰지 않는 버전을 제거합니다. 가장 확실한 방법입니다.
- 둘 다 사용자 Path(또는 둘 다 시스템 Path)에 있다면, 편집 창에서 원하는 버전의 폴더를 위로 올립니다.
- 원하지 않는 버전이 시스템 Path에 있고 원하는 버전이 사용자 Path에 있다면, 앞에서 설명했듯이 순서를 아무리 바꿔도 시스템 쪽이 이깁니다. 시스템 Path에서 그 항목을 지우거나, 원하는 버전의 폴더를 시스템 Path의 더 앞쪽에 넣어야 합니다.
Java에서 특히 자주 걸리는 함정이 있습니다. Oracle JDK 설치 프로그램은 시스템 Path 앞쪽에 C:\Program Files\Common Files\Oracle\Java\javapath(구버전은 Program Files (x86) 아래)를 추가하는데, 이 폴더에는 마지막에 설치한 Oracle Java를 가리키는 java.exe가 들어 있습니다. 그래서 다른 JDK를 설치하고 JAVA_HOME을 바꿔도 java -version은 계속 옛날 버전을 보여 줍니다. where java에 javapath가 먼저 나온다면 이 항목을 시스템 Path에서 지우거나 아래로 내리면 됩니다.
JAVA_HOME처럼 변수를 참조하는 패턴
JDK, Maven, Android SDK처럼 “설치 위치”를 다른 도구가 알아야 하는 프로그램은 별도의 변수로 위치를 지정하고, PATH에서는 그 변수를 참조하는 패턴을 많이 씁니다.
- 시스템 변수(또는 사용자 변수)에서 새로 만들기를 누르고, 변수 이름
JAVA_HOME, 값C:\Program Files\Eclipse Adoptium\jdk-21.0.4.7-hotspot처럼 JDK 최상위 폴더를 넣습니다.bin까지 넣으면 안 됩니다. Gradle이나 Maven은 이 값 뒤에\bin\java.exe를 스스로 붙이기 때문에,bin까지 넣으면bin\bin\java.exe를 찾다가 실패합니다. - 같은 쪽(시스템이면 시스템)의 Path에
%JAVA_HOME%\bin항목을 추가합니다.
이렇게 해 두면 JDK 버전을 바꿀 때 JAVA_HOME 값 하나만 고치면 PATH도 함께 따라갑니다.
이 패턴이 동작하려면 Path 값이 레지스트리에 REG_EXPAND_SZ(확장 가능한 문자열) 형식으로 저장되어 있어야 합니다. 이 형식이어야 윈도우가 %JAVA_HOME%을 실제 경로로 바꿔 줍니다. 기본 상태의 Path는 이 형식이고, GUI 편집 창은 %가 들어 있으면 이 형식을 유지합니다. 반면 setx나 일부 스크립트로 덮어쓴 뒤에는 REG_SZ(일반 문자열)로 바뀌어, where java를 해도 못 찾고 echo %PATH% 출력에 %JAVA_HOME%\bin이 글자 그대로 남아 있는 증상이 생깁니다. 형식은 다음 명령으로 확인할 수 있습니다.
reg query HKCU\Environment /v Path
reg query "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /v Path
출력의 두 번째 열이 REG_EXPAND_SZ이면 정상이고, REG_SZ라면 GUI 편집 창에서 Path를 열어 아무 항목이나 수정한 뒤 확인을 눌러 다시 저장하면 대체로 바로잡힙니다.
또 하나, 참조는 같은 수준이나 위쪽 수준의 변수를 쓰는 것이 안전합니다. 시스템 변수가 먼저 만들어진 뒤 사용자 변수가 만들어지므로, 사용자 Path에서 시스템 변수 JAVA_HOME을 참조하는 것은 동작하지만, 시스템 Path에서 사용자 변수를 참조하면 확장되지 않습니다.
자주 추가하는 도구별 경로 예시
아래는 기본 설치 위치 기준의 예시입니다. 버전 번호나 사용자 이름은 자신의 환경에 맞게 바꾸고, 반드시 탐색기로 그 폴더에 실제로 .exe가 있는지 확인한 뒤 추가하세요.
| 도구 | PATH에 넣을 폴더 | 비고 |
|---|---|---|
| Python (python.org, 사용자 설치) | C:\Users\<사용자>\AppData\Local\Programs\Python\Python312\ | python.exe 위치 |
| Python의 pip·스크립트 | C:\Users\<사용자>\AppData\Local\Programs\Python\Python312\Scripts\ | pip.exe, pip install로 받은 명령들 |
| Node.js | C:\Program Files\nodejs\ | node.exe, npm.cmd, npx.cmd |
| npm 전역 패키지 | C:\Users\<사용자>\AppData\Roaming\npm | npm install -g로 받은 명령들 |
| Git | C:\Program Files\Git\cmd | 설치 프로그램 기본 옵션 |
| FFmpeg (zip 압축 해제) | C:\ffmpeg\bin | 압축을 푼 위치에 따라 다름 |
| CMake | C:\Program Files\CMake\bin | 설치 시 PATH 추가 옵션 있음 |
| JDK | %JAVA_HOME%\bin | 위 JAVA_HOME 패턴 참고 |
몇 가지 덧붙이면 다음과 같습니다.
- Python은
python.exe가 있는 폴더와Scripts폴더 두 개를 모두 넣어야 합니다. 하나만 넣으면python은 되는데pip나pip install로 받은black,pytest같은 명령이 안 됩니다. - Node.js는 설치 프로그램이 두 폴더를 자동으로 추가합니다.
npm install -g로 받은 명령만 안 된다면npm config get prefix로 전역 설치 위치를 확인하고 그 폴더가 PATH에 있는지 보면 됩니다. - Git 설치 프로그램에는
Git\usr\bin까지 PATH에 넣는 옵션도 있는데, 이 폴더에는find,sort같은 유닉스 도구가 들어 있어 윈도우의 같은 이름 명령을 가려 버립니다. 이 부작용을 알고 쓰는 것이 아니라면 기본값인Git\cmd만 넣는 편이 안전합니다. - FFmpeg은 설치 프로그램 없이 zip으로 배포되므로 PATH 추가를 직접 해야 하는 대표적인 도구입니다. 압축을
C:\Program Files나 사용자 폴더처럼 나중에 지우지 않을 위치에 풀고,bin폴더를 추가합니다. 다운로드와 사용법은 FFmpeg 영상·오디오 처리 가이드를 참고하세요. - winget으로 설치한 포터블 패키지(zip 형태 도구)는
%LOCALAPPDATA%\Microsoft\WinGet\Links에 바로 가기가 만들어지고, 이 폴더가 사용자 Path에 자동으로 추가됩니다. 설치 직후 명령이 안 된다면 대부분 터미널을 새로 열지 않아서입니다.
고치기 전에 백업하고, 망가졌을 때 되돌리는 법
PATH 편집은 실수 한 번으로 기존 항목을 지워 버리기 쉬운 작업이고, 윈도우의 환경 변수 창에는 “되돌리기” 기능이 없습니다. 고치기 전에 현재 값을 레지스트리 파일로 내보내 두면 언제든 원래대로 돌릴 수 있습니다.
:: 사용자 환경 변수 백업 (일반 권한)
reg export HKCU\Environment "%USERPROFILE%\Desktop\user-env-backup.reg"
:: 시스템 환경 변수 백업 (관리자 권한 cmd)
reg export "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "%USERPROFILE%\Desktop\system-env-backup.reg"
reg export는 REG_EXPAND_SZ 형식까지 그대로 보존하므로, 단순히 echo %PATH% 출력을 메모장에 복사해 두는 것보다 정확합니다. 되돌릴 때는 백업한 .reg 파일을 더블클릭해 병합(시스템 쪽은 관리자 권한 필요)한 뒤 로그아웃했다가 다시 로그인합니다. 레지스트리를 직접 되돌리는 방법은 변경 알림을 보내지 않으므로, 탐색기가 새 값을 받도록 로그아웃이 필요합니다.
백업 없이 PATH가 망가져 ipconfig나 notepad 같은 기본 명령까지 안 된다면, 시스템 Path에 윈도우 기본 항목이 남아 있는지부터 확인하세요. 대부분의 기본 명령은 아래 항목만 있으면 다시 동작합니다.
%SystemRoot%\system32
%SystemRoot%
%SystemRoot%\System32\Wbem
%SYSTEMROOT%\System32\WindowsPowerShell\v1.0\
%SYSTEMROOT%\System32\OpenSSH\
이 다섯 개를 시스템 Path 맨 위에 복구한 다음, 개발 도구 폴더는 위의 도구별 예시를 보며 하나씩 다시 추가하면 됩니다. 프로그램 설치 프로그램을 수정(Modify) 이나 복구(Repair) 모드로 다시 실행하면 자기 경로를 다시 넣어 주는 경우도 많습니다.