Crontab 파이썬 스크립트 실행 안될 때 환경변수 PATH 문제 해결 완벽 정리

Crontab에 Python 스크립트를 등록했는데 수동 실행은 되지만 예약 실행은 실패한다면, 십중팔구 환경변수(PATH) 문제입니다. Cron은 로그인 셸이 아니기 때문에 .bashrc.bash_profile에 설정한 PYTHONPATH, ORACLE_HOME, LD_LIBRARY_PATH 등을 읽지 못하며, 이로 인해 ModuleNotFoundErrorDISPLAY 미설정 오류가 발생합니다. 이 글에서는 실전에서 마주친 사례를 바탕으로 원인 진단부터 로그 기반 디버깅, 그리고 완벽한 해결 방법까지 정리합니다.


Crontab파이썬스크립트실행안될때환경변수PATH문제해결완벽정리



1. Crontab 파이썬 실행 실패의 3가지 주요 원인

Cron 환경에서 Python 스크립트가 동작하지 않는 이유는 크게 세 가지로 압축됩니다.

  • 환경변수 미적용: Crontab은 최소한의 환경변수(PATH=/usr/bin:/bin 수준)만 로드하므로, 가상환경 경로나 라이브러리 경로를 인식하지 못합니다.
  • 상대경로 사용: 스크립트 내부에서 ./config.json 같은 상대경로를 사용하면 Cron의 작업 디렉토리(보통 /root 또는 /home/user)에서 파일을 찾지 못해 실패합니다.
  • GUI 의존성: Selenium, PyAutoGUI 등 GUI 라이브러리는 DISPLAY 환경변수가 필요한데, Cron 환경에는 X11 디스플레이가 없어 오류가 발생합니다.

추가로 실행권한 부재(스크립트나 쉘에 chmod +x 미적용), 로그 디렉토리 권한 오류(로그 경로에 쓰기 권한 없음), 계정 패스워드 만료(PAM 인증 실패)도 빈번한 원인입니다.

2. 해결 방법: 환경변수 래퍼 쉘 스크립트 작성

가장 확실한 해결책은 환경변수를 export하는 쉘 스크립트를 만들어 Crontab에서 호출하는 방식입니다. 아래는 실전 예시입니다.

Step 1: 환경변수 설정 쉘 스크립트 작성 (path_set.sh)

#!/bin/bash
# /home/user/scripts/path_set.sh

export PYTHONPATH=/home/user/myproject
export ORACLE_HOME=/opt/oracle/instantclient_19_8
export LD_LIBRARY_PATH=$ORACLE_HOME:$LD_LIBRARY_PATH
export PATH=/usr/local/bin:/usr/bin:/bin

# 작업 디렉토리 이동 (상대경로 문제 해결)
cd /home/user/myproject

# Python 스크립트 실행 (절대경로 사용)
/usr/bin/python3 /home/user/myproject/crawler.py

Step 2: 실행권한 부여

chmod +x /home/user/scripts/path_set.sh

Step 3: Crontab 등록 (로그 리다이렉션 포함)

crontab -e

아래와 같이 등록합니다. 2>&1는 표준 에러(stderr)를 표준 출력(stdout)으로 리다이렉션하여 로그 파일에 함께 기록하는 옵션입니다.

# 평일 오전 10시에 실행, 로그는 /data/log/cron.log에 누적
0 10 * * 1-5 /bin/bash /home/user/scripts/path_set.sh >> /data/log/cron.log 2>&1

꿀팁: 로그 디렉토리(/data/log)가 존재하는지, 해당 경로에 쓰기 권한이 있는지 반드시 확인하십시오. mkdir -p /data/log && chmod 755 /data/log로 생성 및 권한 부여를 권장합니다.

3. Selenium 등 GUI 라이브러리 사용 시 추가 설정

Selenium이나 PyAutoGUI처럼 그래픽 환경이 필요한 라이브러리는 가상 디스플레이(Xvfb)를 사용해야 합니다.

가상 디스플레이 설치 및 적용

# Ubuntu/Debian 기준
sudo apt-get update
sudo apt-get install xvfb

# Python 패키지 설치
pip3 install pyvirtualdisplay

Python 스크립트 상단에 아래 코드를 추가합니다.

from pyvirtualdisplay import Display

display = Display(visible=0, size=(1920, 1080))
display.start()

# 이후 Selenium 등 GUI 코드 작성

또는 쉘 스크립트에서 DISPLAY 환경변수를 직접 지정할 수도 있습니다.

export DISPLAY=:99
Xvfb :99 -screen 0 1920x1080x24 &
/usr/bin/python3 /home/user/myproject/crawler.py

주의: Xvfb 프로세스가 좀비 프로세스로 남지 않도록, 스크립트 종료 시 killall Xvfbdisplay.stop()을 호출하는 것을 권장합니다.

4. 로그 기반 디버깅: syslog와 cron 상태 확인

Cron 실행 여부를 확인하려면 시스템 로그를 반드시 점검해야 합니다.

로그 위치

  • Ubuntu/Debian: /var/log/syslog
  • CentOS/RHEL: /var/log/cron

Cron 실행 기록 확인

grep CRON /var/log/syslog | tail -20

정상적으로 실행되었다면 아래와 같은 로그가 남습니다.

Jan 15 10:00:01 server CRON[12345]: (user) CMD (/bin/bash /home/user/scripts/path_set.sh >> /data/log/cron.log 2>&1)

PAM 인증 오류 (패스워드 만료)

만약 아래와 같은 메시지가 보인다면, Cron 실행 계정의 패스워드가 만료된 상태입니다.

crond: (root) FAILED to authorize user with PAM (Authentication token is no longer valid; new one required)

해결 방법은 간단합니다.

# 패스워드 만료 여부 확인
chage -l root

# 패스워드 갱신
passwd root

# crond 재시작
systemctl restart cron  # Ubuntu/Debian
systemctl restart crond # CentOS/RHEL

Cron 데몬 상태 확인

systemctl status cron   # Ubuntu/Debian
systemctl status crond  # CentOS/RHEL

데몬이 중지되어 있다면 systemctl start cron으로 재시작하십시오.

5. 자주 쓰는 Crontab 명령어 및 디버깅 체크리스트

Crontab 기본 명령어

  • crontab -e: 현재 사용자의 Crontab 편집
  • crontab -l: 등록된 Cron 작업 목록 확인
  • crontab -r: 모든 Cron 작업 삭제 (주의!)
  • crontab -u username -e: 특정 사용자의 Crontab 편집 (root 권한 필요)

디버깅 체크리스트

  1. 절대경로 사용 여부: Python 인터프리터, 스크립트 경로, 로그 경로 모두 절대경로로 작성했는가?
  2. 환경변수 설정: 쉘 스크립트에 필요한 환경변수를 export했는가?
  3. 작업 디렉토리 명시: cd /path/to/project로 작업 디렉토리를 이동했는가?
  4. 실행권한: 쉘 스크립트와 Python 스크립트에 실행권한(chmod +x)이 있는가?
  5. 로그 디렉토리 권한: 로그 파일을 쓸 디렉토리에 쓰기 권한이 있는가?
  6. 로그 리다이렉션: >> /path/to/log 2>&1로 표준 출력과 에러를 모두 기록하고 있는가?
  7. Cron 데몬 상태: systemctl status cron으로 데몬이 실행 중인지 확인했는가?
  8. 계정 패스워드: chage -l로 패스워드 만료 여부를 확인했는가?

정리

Crontab에서 Python 스크립트가 실행되지 않는 문제는 대부분 환경변수 미적용상대경로 사용에서 비롯됩니다. 환경변수를 export하는 쉘 래퍼 스크립트를 만들어 절대경로로 호출하고, 로그 리다이렉션(2>&1)으로 에러를 기록하며, grep CRON /var/log/syslog로 실행 여부를 확인하는 습관을 들이면 대부분의 문제를 예방할 수 있습니다. GUI 라이브러리를 사용한다면 Xvfb 가상 디스플레이를 반드시 설정하고, 패스워드 만료 여부도 정기적으로 점검하십시오.

Action Item: 지금 당장 crontab -l로 등록된 작업을 확인하고, 로그 리다이렉션이 없다면 >> /path/to/log 2>&1을 추가하십시오. 로그 없이는 디버깅이 불가능합니다.





# 함께 보면 좋은 글

댓글