달나라 노트

Python Basic : Crontab (Python code scheduler 주기적으로 Python 파일 돌리기) 본문

Python/Python Basic

Python Basic : Crontab (Python code scheduler 주기적으로 Python 파일 돌리기)

CosmosProject 2021. 9. 17. 00:25
728x90
반응형

 

 

 

 

 

Mac에는 Crontab이라는 기능이 있습니다.

간단하게 설명하면 어떤 코드가 적힌 파일을 재가 원하는 시간에 맞춰 주기적으로 실행해주는 기능입니다.

 

이 기능을 이용하면 내가 따로 신경쓰지 않고도 컴퓨터만 켜져있으면 작성해둔 파일(python file[.py], shell script file[.sh] 등)을 주기적으로 실행시킬 수 있습니다.

 

근데 컴퓨터가 켜져있는 상태이어야만 합니다.

 

맥북의 경우 비밀번호를 입력하게되는 로그인 창이 있는데 최소한 이 로그인창인 상태를 유지해야합니다.

 

만약 맥북을 덮거나 컴퓨터를 아예 종료해버리면 Crontab은 실행되지 않습니다.

(따라서 컴퓨터를 아예 종료해도 실행되어야만 하는 상황이라면 AWS같은 서버를 이용해야만 합니다.)

 

 

 

 

그러면 이제 Crontab 사용법을 알아봅시다.

 

먼저 주기적으로 실행시킬 Python file이 있어야겠죠.

 

directory 구조는 위와 같습니다.

 

저는 list_update.py를 주기적으로 실행시키도록 할 예정입니다.

 

 

 

다음은 list_update.py의 내용입니다.

import pandas as pd

dict_test = {
    'col1': [1, 2, 3],
    'col2': [4, 5, 6]
}

df_test = pd.DataFrame(dict_test)

df_test.to_excel('item_list.xlsx', index=False, sheet_name='item_list')
print('Process finished')

 

 

 

 

일단 crontab은 사람이 아닌 컴퓨터가 파일을 실행시키는 것이므로 컴퓨터가 실행시킬 파일에 접근할 권한을 받아야 합니다.

 

 

 

Terminal $ chmod +x /Users/Code/list_update/list_update.py

Terminal을 키고 위처럼 chmod +x 명령어를 입력해줍시다.

chmod +x [경로] 명령어는 [경로]에 적힌 파일에 접근할 권한을 나의 컴퓨터에게 부여해주는 명령어입니다.

 

 

 

 

또한 cron application이 disc에 접근할 권한도 부여해야 합니다.

 

맥북의 설정 -> 보안 및 개인 정보 보호 -> 개인 정보 보호 탭을 들어갑시다.

 

그러면 위와 같은 화면이 나오는데 왼쪽 아래 자물쇠를 클릭하여 잠금을 해제해줍니다.

 

 

 

 

그리고 + 버튼을 누릅시다.

 

 

 

 

 

그러면 위처럼 application을 찾을 수 있는 화면이 나오는데 Command + Shift + g를 눌러 /usr/sbin/cron을 입력해줍시다.

 

 

 

 

 

 

위에서 지정한 경로로 이동이 되며 cron applicatoin이 나옵니다.

열기를 눌러줍시다.

 

 

 

그리고 위처럼 cron에 체크를 하여 전체 디스크 접근 권한을 부여해준 후 좌측 하단의 자물쇠를 잠궈줍니다.

 

 

 

 

 

 

 

 

 

Terminal $ crontab -e

이제 Crontab을 설정해줄텐데 위처럼 Terminal을 열고 아무 경로에서나 crontab -e 명령어를 입력합니다.

그러면 Crontab 내용을 입력할 수 있는 vim editor 화면으로 들어와집니다.

 

 

 

 

 

0 8 * * * /Users/.conda/envs/bin/python /Users/Code/list_update/list_update.py > /Users/Code/list_update/log/list_update_log_`date +\%Y\%m\%d`_`date +\%H\%M\%S`.log 2>&1

/Users/robin/Documents/Robin/Code/slack_api/list_update/list_update.py

해당 vim editor에 위처럼 입력해줍시다.

 

위 내용이 바로 Crontab의 스케줄링을 이용하는 방법인데 한 부분씩 나눠서 알아봅시다.

 

 

 

 

 

 

 

0 8 * * *

먼저 가장 앞에 있는 이 부분입니다.

이 부분을 해석하면 매일 8시 00분에 실행한다는 의미입니다.

 

어떤 job을 실행할 시점을 정할 때 위 같은 형태의 표현을 많이 쓰는데 이것을 Cron expression이라고 합니다.

 

 

┌──────────── minute (0 ~ 59)
| ┌────────── hour (1 ~ 23)
| | ┌──────── day of month (1 ~ 31)
| | | ┌────── month (1 ~ 12)
| | | | ┌──── day of week (0 - 6) -> Sunday=0, Monday=1, ..., Saturday=6
0 8 * * *

각 부분의 의미는 위와 같습니다.

 

(https://docs.oracle.com/cd/E12058_01/doc/doc.1014/e12030/cron_expressions.htm

위 링크를 클릭하면 참고 cron expression에 대한 설명이 있는 웹 페이지로 이동됩니다.)

 

 

위 내용을 토대로 여러 cron expression의 예시를 보면 다음과 같습니다.

0 8 * * *          --> 매일 8시 0분에 실행
50 15 * * *        --> 매일 15시 50분에 실행
15,45 8,16 * * *   --> 매일 8시 15분, 8시 45분, 16시 15분, 16시 45분에 실행
10 10-14 * * *     --> 매일 10시 10분, 11시 10분, 12시 10분, 13시 10분, 14시 10분에 실행
50 15 1,11,15 * *  --> 매달 1일 15시 50분, 11일 15시 50분, 15일 15시 50분에 실행

 

 

 

 

 

 

 

... /Users/.conda/envs/bin/python /Users/Code/list_update/list_update.py > ...

두번째는 위 부분입니다.

위 부분은 Python file을 실행한다는 부분입니다.

 

저희가 terminal에서 python file을 실행할 때 python file.py 이런식으로 적죠.

 

따라서 Crontab에서도 이와 동일하게 사용할 python interpreter와 실행할 python file의 경로를 적어주는 것입니다.

 

저는 conda interpreter를 쓰기 때문에 /Users/.conda/envs/bin/python 라고 적었습니다.

 

interpreter에 관한 내용은 아래 링크 참고하시면 됩니다.

https://cosmosproject.tistory.com/387

 

 

 

 

 

 

... > /Users/Code/list_update/log/list_update_log_`date +\%Y\%m\%d`_`date +\%H\%M\%S`.log 2>&1

마지막은 이 부분은 사실 필수적인 부분은 아닌데 적어주는 것이 좋습니다.

 

왜냐면 이 부분은 Python code를 실행하면서 출력되는 모든 텍스트들을 담아 log file을 생성해주는 부분이기 때문입니다.

 

log file이 생성될 경로를 적어주고 있으며 log file의 패턴은 다음 부분입니다.

list_update_log_`date +\%Y\%m\%d`_`date +\%H\%M\%S`.log

이것은 현재 시간을 원하는 형식으로 바꿔준것으로서, 예시로 생성된 log file의 이름은 아래와 같습니다.

list_update_log_20210916_081503.log

이렇게 파일에 실행된 날짜와 시간을 적어두고 python 실행 시 출력된 모든 텍스트들을 담아서 log 파일로 생성해두면

실행 내역과 Error 내역까지 모두 기록되기 때문에 debuging에도 매우 유용합니다.

 

 

 

제대로 실행됐다면 위처럼 log file이 생성된 것을 볼 수 있습니다.

 

 

 

 

 

 

 

 

 

 

이번엔 shell script(.sh) 파일을 Crontab에 등록해봅시다.

 

source ~/.bash_profile

python list_update.py

shell script(.sh) 파일의 내용은 위와 같습니다.

source ~~ 부분은 .bash_profile에 있는 환경변수를 참조하기 위해서 적어주었으며

python ~~.py 부분은 python file을 실행하기 위한 부분입니다.

 

위 예시에서는 source로 .bash_profile을 사용했지만

만약 zsh shell을 사용해서 .zprofile 파일에 환경변수를 담아뒀다면 source ~/.zprofile로 수정해주면 됩니다.

 

 

 

shell script 파일의 crontab 실행은 Python보다 더 간단합니다.

crontab -e 명령어를 terminal에 입력한 후 crontab vim editor에서 아래 내용을 입력해줍시다.

(vim editor 관련 내용은 아래의 링크를 참고하시면 됩니다.

https://cosmosproject.tistory.com/269)

 

0 8 * * * /Users/Code/list_update/list_update.sh > /Users/Code/list_update/log/list_update_log_`date +\%Y\%m\%d`_`date +\%H\%M\%S`.log 2>&1

Python과는 다르게 shell script 파일은 terminal에서 직접 실행할 수 있으므로 실행할 shell script 파일의 경로만 입력해주면 됩니다.

 

그 외에는 모두 같습니다.

 

(.sh 파일도 chmod +x [경로/파일] 명령어로 권한을 부여해줘야하는 것 참고바랍니다.)

 

 

 

 

 

간혹 Shell Script파일을 Crontab으로 돌리는 경우 Shell Script 파일 내에서 실행하는 Python파일을 찾지 못했다는 에러가 발생할 수 있습니다.

 

그럴때에는 아래처럼 Shell Script 내에서 직접 Python 파일이 있는 경로로 이동하도록 cd 명령어를 적어주면 됩니다.

source ~/.bash_profile

cd /Users/Code/list_update/
python list_update.py

 

 

 

 

또한 간혹 이유를 알 수 없는 Error가 뜬다면

source ~/.bash_profile

cd /Users/Code/list_update/
python -m list_update

python -m 명령어를 사용하여

Python file을 module로써 실행한다는 내용으로 코드를 바꾸면 문제없이 실행될 때도 있습니다.

 

 

 

 

 

 

 

728x90
반응형
Comments