파이썬 예약 실행 오류 해결 순서: PATH·작업 폴더·가상환경 확인법

터미널에서는 되는데 예약 실행에서 실패하는 파이썬 예약 실행 오류는 코드보다 실행 환경의 차이에서 시작하는 경우가 많습니다. 먼저 PATH와 현재 작업 폴더를 기록한 뒤 실제로 실행된 sys.executable을 확인하고, 그 다음 가상환경 인터프리터와 파일 경로를 절대경로로 고정하면 원인을 빠르게 좁힐 수 있습니다.

터미널과 예약 실행은 같은 프로세스가 아닙니다

터미널에서 python app.py가 성공했다는 사실은 로그인 셸이 준비한 환경에서 성공했다는 뜻입니다. 예약 실행은 별도의 프로세스로 시작하므로 셸 설정 파일이 적용되지 않거나, 터미널과 다른 PATH·작업 폴더·Python을 사용할 수 있습니다.

그래서 ModuleNotFoundError는 패키지가 무조건 없다는 뜻이 아닙니다. 예약 실행이 프로젝트의 가상환경이 아닌 다른 Python을 호출했는지부터 확인해야 합니다. FileNotFoundError도 파일이 사라졌다는 뜻에 앞서, 상대경로의 기준이 터미널과 달라졌는지 살펴볼 필요가 있습니다.

먼저 남길 환경 진단 로그

원인을 추측하기 전에 예약 작업이 실제로 본 환경을 출력하게 합니다. 다음 코드는 외부 API나 비밀값을 호출하지 않고 실행 위치만 기록합니다.

from pathlib import Path
import os
import sys

print("executable:", sys.executable)
print("cwd:", os.getcwd())
print("script_dir:", Path(__file__).resolve().parent)
print("path:", os.environ.get("PATH", ""))

sys.executable은 현재 실행 중인 Python 인터프리터 경로를 보여 줍니다. os.getcwd()는 프로세스의 현재 작업 디렉터리를 보여 주므로, 두 값은 각각 “어떤 Python인가”와 “상대경로의 기준은 어디인가”를 나누어 확인하게 해 줍니다.

운영 로그에는 표준 출력과 표준 오류를 함께 남기는 편이 좋습니다. 예약 실행에서 화면을 직접 볼 수 없을 때도 이 네 가지 값과 예외 전문이 있어야 실패 지점을 재현할 수 있습니다. 로그에 토큰, 비밀번호, 개인 경로가 불필요하게 포함되지 않는지도 함께 확인하십시오.

확인 순서 1: PATH와 명령 이름

예약 작업에서 python 또는 외부 명령을 이름만으로 호출하면 PATH에 따라 결과가 달라질 수 있습니다. command not found가 나오거나, 모듈이 터미널에서만 보인다면 PATH를 먼저 의심할 만합니다.

다만 PATH를 길게 복사해 붙이는 것보다 실행 파일을 직접 지정하는 편이 재현성이 높습니다. POSIX 계열에서는 다음처럼 프로젝트 디렉터리의 .venv/bin/python을 사용합니다.

/path/to/project/.venv/bin/python /path/to/project/app.py

Windows에서는 가상환경의 Scripts/python.exe를 직접 지정하는 방식으로 같은 목적을 달성합니다. 활성화 명령을 예약 작업에서 흉내 내기보다, 예약 작업이 바로 사용할 인터프리터를 명시하는 쪽이 확인하기 쉽습니다.

확인 순서 2: 현재 작업 폴더와 파일 경로

open("data/input.json") 같은 상대경로는 소스 파일이 있는 폴더가 아니라 현재 작업 폴더를 기준으로 해석됩니다. 스케줄러가 프로젝트 폴더가 아닌 다른 곳에서 프로세스를 시작하면 터미널에서 있던 파일을 찾지 못할 수 있습니다.

작업 설정에서 프로젝트 폴더를 명시할 수 있다면 그렇게 하고, 코드에서도 기준을 분명히 하십시오. 예를 들어 실행 파일과 함께 둔 파일이라면 Path(__file__).resolve().parent에서 경로를 만들 수 있습니다.

from pathlib import Path

BASE_DIR = Path(__file__).resolve().parent
input_path = BASE_DIR / "data" / "input.json"

반대로 사용자가 지정한 작업 폴더가 의미 있는 프로그램이라면 무조건 소스 기준 경로로 바꾸지 말고, 그 폴더를 예약 실행 설정에 명시하는 편이 맞습니다. 핵심은 상대경로를 없애는 것 자체가 아니라 어떤 기준을 의도했는지 고정하는 것입니다.

확인 순서 3: 실제 Python과 가상환경

가상환경에는 별도의 Python 인터프리터와 패키지가 들어갑니다. 터미널에서 가상환경을 활성화한 뒤 성공했더라도 예약 프로세스가 그 활성화 상태를 물려받는다고 가정하면 안 됩니다.

프로젝트에 다음과 같은 실행 경로가 있다면 예약 작업은 이를 직접 사용하도록 구성합니다.

POSIX:   /path/to/project/.venv/bin/python
Windows: C:\path\to\project\.venv\Scripts\python.exe

그 뒤 진단 로그의 sys.executable이 예상한 경로인지 확인하십시오. 경로가 맞는데도 모듈 오류가 난다면 그 인터프리터에 필요한 패키지가 설치되어 있는지, 예약 작업이 다른 프로젝트 폴더를 보고 있지 않은지를 분리해 확인합니다. 가상환경 디렉터리를 다른 위치로 단순 복사해 쓰는 방식은 경로에 의존할 수 있으므로, 위치를 바꿨다면 새 위치에서 재생성하는 편이 안전합니다.

가상환경을 만드는 선택과 시스템 Python·pipx의 역할이 헷갈린다면 venv·pipx·apt 선택과 확인법을 이어서 참고할 수 있습니다.

오류별로 원인을 좁히는 표

증상 먼저 확인할 값 다음 판단
command not found 예약 프로세스의 PATH와 실행 명령 실행 파일 절대경로 지정
ModuleNotFoundError sys.executable과 작업 폴더 해당 인터프리터의 패키지·프로젝트 경로 확인
FileNotFoundError os.getcwd()와 파일 경로 작업 폴더를 명시하거나 기준 경로를 코드에 고정
로그가 없음 stdout·stderr 연결과 로그 경로 출력 리디렉션과 예외 기록 추가

환경변수 자체가 필요한 자동화라면 값이 전달됐는지도 별도로 확인해야 합니다. os.getenv()가 None일 때의 점검 순서는 파이썬 os.getenv()가 None일 때 확인하는 순서에서 다루고 있습니다. 로그를 콘솔과 파일로 나누어 운영하려면 파이썬 로그 콘솔·파일 레벨 분리도 다음 질문에 해당합니다.

예약 설정을 고정하기 전 최종 점검

저라면 예약 실행을 배포하기 전에 다음 네 가지를 한 번에 확인합니다.

  1. 실행 명령이 python이라는 이름에 의존하지 않고 올바른 가상환경 인터프리터를 가리키는가?
  2. 작업 폴더가 설정되어 있으며, 코드의 상대경로 기준과 의도가 일치하는가?
  3. sys.executable, os.getcwd(), PATH와 예외 전문이 안전한 로그에 남는가?
  4. 터미널 성공 여부가 아니라 예약 프로세스에서 실제로 같은 입력·권한·환경이 제공되는가?

이 순서에서 첫 번째 로그가 sys.executable과 cwd를 보여 주면, 패키지 설치 문제와 경로 문제를 섞어 고치는 일을 피할 수 있습니다. 이후에도 실패한다면 해당 로그를 기준으로 환경변수 전달, 파일 권한, 외부 서비스 응답처럼 남은 조건을 하나씩 분리해 확인하면 됩니다.

Leave a Comment