- 공유 링크 만들기
- X
- 이메일
- 기타 앱
이 글의 목적은 Python 실행 시 PATH 충돌로 인해 전역 Python 또는 다른 배포판이 먼저 잡히는 문제를 원인별로 진단하고, 가상환경(venv)이 항상 우선순위로 선택되도록 Windows·macOS·Linux·VS Code·작업 스케줄러 환경까지 포함해 재현 가능한 절차로 정리하는 데 있다.
1. 문제의 핵심: “python”이 무엇을 가리키는지 매번 달라지는 구조이다
운영체제는 “python”이라는 문자열을 실행 파일로 바꾸기 위해 우선순위 규칙을 적용하다.
대표적으로 PATH 환경변수에 등록된 폴더의 순서, 실행 별칭(App Execution Aliases), 셸 초기화 스크립트, 런처(py), 개발도구(VS Code) 자체 설정, 다른 환경관리자(pyenv/conda/poetry/pipx) shims가 동시에 개입하면서 충돌이 발생하다.
가상환경(venv)은 활성화 시 현재 셸 프로세스의 PATH 맨 앞에 venv의 실행 폴더를 “임시로” 끼워 넣는 방식으로 동작하다.
따라서 활성화가 제대로 안 되었거나, 활성화는 되었으나 다른 메커니즘이 우선되거나, 아예 활성화 없이 “python”만 실행하는 습관이 있으면 전역 Python이 실행되다.
2. 30초 진단: 지금 실행되는 Python의 정체를 확정하다
2.1 공통 진단 코드이다
python -c "import sys; print(sys.executable); print(sys.prefix); print(getattr(sys, 'base_prefix', ''));" python -m pip -V sys.executable이 실제 실행 파일의 절대경로이다.
sys.prefix와 base_prefix가 다르면 가상환경(venv) 내부일 가능성이 높다.
pip 경로가 전역으로 표시되면 가상환경이 우선되지 않는 상태이다.
2.2 Windows 진단 명령이다
where python where pip py -0p powershell -NoProfile -Command "Get-Command python | Format-List *" where python 결과가 여러 줄이면 “python” 후보가 여럿이라는 의미이다.
Get-Command로 alias, function, application 중 무엇으로 해석되는지 확인하다.
py -0p는 설치된 Python 런타임 목록을 경로와 함께 보여주다.
2.3 macOS/Linux 진단 명령이다
which -a python python3 pip pip3 type -a python python3 echo "$PATH" which -a 또는 type -a에서 위에 나오는 것이 우선 실행되다.
3. 증상-원인-해결을 한 번에 매칭하다
| 증상이다 | 가능 원인이다 | 우선 해결책이다 |
|---|---|---|
| venv를 켰는데도 python이 전역 경로이다 | 활성화 스크립트 미실행, 다른 셸/터미널 사용, 스크립트 실행 정책 차단이다 | 정확한 Activate 실행, 실행 정책 조정, 터미널 프로파일 통일이다 |
| pip만 전역으로 잡히다 | pip를 직접 호출해 PATH의 다른 pip가 먼저 잡히다 | python -m pip만 사용하다 |
| Windows에서 python이 Microsoft Store로 열린다 | App Execution Aliases가 python.exe를 가로채다 | 설정에서 python 실행 별칭을 끄다 |
| VS Code에서 선택한 인터프리터와 터미널 python이 다르다 | VS Code 인터프리터 설정과 터미널 초기화가 분리되어 있다 | 프로젝트 venv 고정 및 터미널 활성화 스크립트 일치이다 |
| 작업 스케줄러/서비스에서만 전역 Python이 실행되다 | 비대화형 환경에서 activate가 실행되지 않다 | venv의 python 절대경로로 실행하다 |
| pyenv/conda/poetry/pipx 설치 후 갑자기 경로가 바뀌다 | shim 경로가 PATH 상단으로 올라가다 | PATH 순서 재정의 및 프로젝트별 실행 규칙 확정이다 |
4. 원칙: “활성화에 기대지 말고 실행 경로를 고정하다”가 최종 해법이다
가상환경 활성화는 편의 기능이며, 안정성의 최종 답이 아니다.
가장 확실한 방법은 “그 가상환경의 python”을 절대경로로 호출하거나, 현재 디렉터리 기준 상대경로로 호출하는 습관을 만드는 것이다.
4.1 프로젝트에서 항상 통하는 실행 패턴이다
# Windows .\.venv\Scripts\python.exe -m pip install -r requirements.txt .\.venv\Scripts\python.exe your_script.py
macOS/Linux
./.venv/bin/python -m pip install -r requirements.txt
./.venv/bin/python your_script.py
이 방식은 PATH가 무엇이든 영향을 거의 받지 않다.
5. Windows에서 venv 우선순위를 확실히 만드는 절차이다
5.1 1단계: Microsoft Store 실행 별칭을 끄다
Windows는 “앱 실행 별칭” 기능으로 python.exe를 스토어로 연결할 수 있다.
이 기능이 켜져 있으면 PATH보다 앞서 동작하는 것처럼 보이며 혼동을 만들다.
설정 앱에서 “앱” 관련 메뉴의 “앱 실행 별칭”에서 python.exe, python3.exe 항목을 끄다.
5.2 2단계: PATH를 “사용자 PATH 우선, 시스템 PATH 후순위”로 정리하다
Windows는 일반적으로 사용자 PATH와 시스템 PATH를 합쳐서 검색하다.
중요한 점은 사용자 PATH에 여러 Python 경로가 섞이면 우선순위가 더 복잡해지다.
원칙은 다음과 같이 정리하다.
첫째, 프로젝트는 venv로 해결하다.
둘째, 전역 Python은 하나만 “의도적으로” 남기다.
셋째, 여러 버전이 필요하면 PATH가 아니라 py 런처로 선택하다.
5.3 3단계: py 런처를 올바르게 쓰다
Windows의 py 런처는 Python 버전 선택에 강하다.
다만 venv 안에서는 py가 항상 venv를 우선한다고 기대하면 혼란이 생기다.
프로젝트 작업에서는 “python” 또는 “.venv의 python 절대경로”로 통일하는 편이 안전하다.
전역 버전 확인이나 특정 버전으로 venv를 만들 때만 py를 쓰는 방식이 안정적이다.
# 특정 버전으로 venv 생성 예시이다 py -3.12 -m venv .venv # 생성 후에는 venv python을 직접 쓰는 편이 안전하다 .\.venv\Scripts\python.exe -V 5.4 4단계: PowerShell 활성화가 막힐 때의 표준 처리이다
PowerShell은 스크립트 실행 정책 때문에 Activate.ps1 실행이 차단될 수 있다.
보안 요구사항을 해치지 않으면서 개발 터미널에서만 완화하는 방식이 실무적이다.
# 현재 PowerShell 세션에서만 허용하는 예시이다 Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass # venv 활성화이다 .\.venv\Scripts\Activate.ps1 조직 정책이 강제인 환경에서는 위 명령조차 차단될 수 있다.
그 경우는 활성화에 매달리지 말고 4장에 제시한 절대경로 실행 패턴으로 전환하는 것이 정답이다.
5.5 5단계: CMD와 PowerShell의 활성화 스크립트를 혼동하지 않다
CMD는 activate.bat, PowerShell은 Activate.ps1, Git Bash는 activate를 사용하다.
다른 셸에서 다른 스크립트를 실행하면 활성화가 안 되었는데 된 것처럼 착각하다.
# CMD이다 .\.venv\Scripts\activate.bat # PowerShell이다 .\.venv\Scripts\Activate.ps1 # Git Bash이다 source ./.venv/Scripts/activate 6. macOS/Linux에서 venv 우선순위를 확실히 만드는 절차이다
6.1 셸 초기화 파일에서 PATH 주도권이 누구인지 확인하다
zsh은 .zshrc, bash는 .bashrc 또는 .bash_profile이 PATH 구성의 핵심이다.
pyenv, conda, brew, poetry 등이 PATH 상단을 점유하면 “python”의 의미가 바뀌다.
중요 원칙은 “프로젝트는 venv로 고정 실행”이며, 전역 PATH는 최소화하다.
6.2 활성화가 확실히 필요하면 source를 사용하다
활성화는 현재 셸의 환경변수를 바꾸는 작업이므로 source로 실행해야 한다.
python3 -m venv .venv source .venv/bin/activate python -V python -m pip -V 스크립트 파일에서 activate를 실행해도, 스크립트가 서브셸에서 끝나면 활성화 상태는 사라지다.
따라서 자동화에서는 활성화 대신 “.venv/bin/python” 직접 실행이 더 안전하다.
6.3 pyenv를 쓰는 경우의 안정 규칙이다
pyenv는 shims를 PATH 상단에 넣어 버전 선택을 제어하다.
이 상태에서 venv를 만들면 “어떤 Python으로 venv를 만들었는지”가 중요해지다.
프로젝트마다 다음 패턴을 고정하면 충돌이 크게 줄다.
# 원하는 버전을 명확히 선택하고 venv를 만들다 pyenv local 3.12.2 python -m venv .venv
실행은 venv python으로 고정하다
./.venv/bin/python -V
7. VS Code에서 “선택한 인터프리터”와 “터미널 python”을 일치시키다
7.1 VS Code는 두 축이 따로 움직이다
VS Code는 편집기 상단의 인터프리터 선택과, 통합 터미널의 셸 초기화가 분리되어 있다.
따라서 인터프리터를 .venv로 선택했어도 터미널이 새로 열릴 때 활성화가 실패하면 PATH는 전역이 되다.
7.2 실무에서 가장 안정적인 고정 방법이다
첫째, 프로젝트 루트에 .venv를 고정하다.
둘째, 실행·디버그·작업(Task)에서 항상 .venv의 python 경로를 사용하다.
셋째, pip는 항상 python -m pip로 통일하다.
# .vscode/settings.json에 들어갈 수 있는 대표 개념 예시이다 # 핵심은 "프로젝트의 .venv를 기준으로 잡는다"는 운영 원칙이다 8. 작업 스케줄러, 서비스, CI에서 venv 우선 실행을 보장하다
8.1 비대화형 환경은 activate가 통하지 않는 경우가 많다
작업 스케줄러나 Windows 서비스, 리눅스 systemd, CI 러너는 로그인 셸이 아니거나 프로파일을 읽지 않다.
이 경우 activate에 기대면 실패 확률이 높다.
8.2 정답 패턴은 “venv python 절대경로로 실행”이다
# Windows 작업 스케줄러 작업(Action) 예시 개념이다 Program/script: C:\path\to\project\.venv\Scripts\python.exe
Add arguments:
C:\path\to\project\run_job.py
Start in:
C:\path\to\project
# Linux systemd/cron 예시 개념이다 /path/to/project/.venv/bin/python /path/to/project/run_job.py 9. 충돌을 원천 차단하는 운영 규칙 10가지이다
9.1 규칙 목록이다
1) 프로젝트마다 .venv를 만들고 저장소 루트에 둔다.
2) 실행은 .venv의 python 절대경로 또는 상대경로로 고정하다.
3) pip는 무조건 python -m pip로 실행하다.
4) 전역 PATH에는 Python을 여러 개 넣지 않다.
5) 다중 버전은 PATH가 아니라 런처(py) 또는 pyenv/conda로 관리하다.
6) Windows에서는 앱 실행 별칭의 python 항목을 비활성화해 혼동을 줄이다.
7) VS Code는 “자동 활성화” 성공 여부에 기대지 말고 실행 경로를 고정하다.
8) 스케줄러/서비스/CI는 activate를 쓰지 말고 venv python으로 직접 실행하다.
9) 팀 규칙으로 “python -m pip, requirements.lock 또는 고정된 의존성 파일”을 강제하다.
10) 진단은 sys.executable과 python -m pip -V로 항상 증거 기반으로 확인하다.
10. 현장에서 바로 쓰는 점검 스크립트 예시이다
10.1 Windows PowerShell 점검 스크립트이다
# 파일명 예시: check_python_path.ps1 이다 Write-Host "=== PATH 상위 일부 ===" $env:PATH.Split(';') | Select-Object -First 10 | ForEach-Object { Write-Host $_ }
Write-Host "`n=== python 후보 ==="
where python
Write-Host "`n=== pip 후보 ==="
where pip
Write-Host "`n=== python 증거 ==="
python -c "import sys; print('executable=', sys.executable); print('prefix=', sys.prefix); print('base_prefix=', getattr(sys,'base_prefix',''))"
Write-Host "`n=== pip 증거 ==="
python -m pip -V
10.2 macOS/Linux Bash 점검 스크립트이다
# 파일명 예시: check_python_path.sh 이다 set -eu
echo "=== PATH 상위 일부 ==="
echo "$PATH" | tr ':' '\n' | head -n 10
echo ""
echo "=== python 후보 ==="
which -a python python3 || true
echo ""
echo "=== pip 후보 ==="
which -a pip pip3 || true
echo ""
echo "=== python 증거 ==="
python3 -c "import sys; print('executable=', sys.executable); print('prefix=', sys.prefix); print('base_prefix=', getattr(sys,'base_prefix',''))"
echo ""
echo "=== pip 증거 ==="
python3 -m pip -V
FAQ
venv를 활성화했는데도 pip가 전역으로 설치되는 이유는 무엇이다?
pip 실행 파일은 PATH에서 찾기 때문에, “pip”를 직접 치면 venv 밖의 pip가 먼저 잡힐 수 있다.
해결책은 pip를 직접 호출하지 않고 python -m pip로만 실행하는 운영 규칙을 적용하는 것이다.
Windows에서 python을 치면 스토어가 열리는 현상은 무엇이다?
Windows의 앱 실행 별칭이 python.exe 호출을 가로채 스토어로 연결하는 동작이다.
설정에서 python 관련 실행 별칭을 끄면 충돌이 줄어들다.
VS Code에서 인터프리터는 .venv인데 터미널은 전역 Python이 나오는 이유는 무엇이다?
편집기 인터프리터 선택과 터미널 셸 초기화는 별개로 동작하다.
터미널 자동 활성화가 실패하면 PATH가 전역 기준으로 남다.
실행·디버그·작업은 .venv의 python 경로로 고정하는 방식이 재현성이 가장 높다.
작업 스케줄러에서만 venv가 적용되지 않는 이유는 무엇이다?
스케줄러는 로그인 셸이 아니어서 activate 스크립트를 실행해도 환경이 기대대로 세팅되지 않다.
Program/script를 venv의 python.exe로 직접 지정하면 가장 확실하다.
가상환경 우선순위 문제를 근본적으로 없애는 “한 줄 규칙”은 무엇이다?
항상 프로젝트의 venv python으로 실행하고, pip는 python -m pip로 실행하는 규칙이다.
- 공유 링크 만들기
- X
- 이메일
- 기타 앱