다양한 주제

crontab

patrick-star 2023. 7. 20. 00:21
728x90

cron은 유닉스 계열 컴퓨터 운영 체제의 시간 기반 잡 스케줄러이다.
작업을 고정된 시간, 날짜, 간격에 주기적으로 실행할 수 있도록 스케줄링하기 위해 cron을 사용한다.

  • 사용환경 : Ubuntu 20.04.6 LTS(GNU/Linux 5.15.0-75-generic x86_64)

설치 및 상태 확인

sudo apt install cron # 설치 
sudo service cron status # 상태 확인 - active이면 크론탭이 실행된 상태인 거고 inactive이면 크론탭을 시작해줘야 한다. 

sudo service cron start # 크론탭 시작 

사용법

① crontab -l : 크론탭으로 설정한 작업들의 리스트를 보여준다.

② crontab -e : 크론탭을 수정할 때 사용한다.

  • 크론탭을 설정할 때 ubuntu에서 제공하는 편집기를 이용해 수정한다.
  • 처음 크론탭을 설정한다면 원하는 편집기를 고를 수 있다.
    • select-editor를 입력해서 원하는 편집기로 바꿀 수도 있고
    • export VISUAL=nano / export EDITOR=nano / export VISUAL=vim 등으로 입력해서 원하는 편집기로 변경할 수 있다.

③ crontab -r : 현재 설정한 크론탭을 삭제한다.

  • 아무런 경고 없이 삭제되기 때문에 주의해서 사용하자.

파일 설정

crontab -e를 통해 크론탭 파일에 접근해서 아래의 방법을 이용해 원하는 설정을 해줄 수 있다.

# 커맨드를 실행한 결과를 메일로 전송하고 싶을 때 
# 수신받을 메일 주소를 적으면 된다. 
# 만약에 MAILTO="" 라고 정의했다면 메일을 보내지 않는다. 
# 그렇지 않고 아무것도 정의하지 않았다면 crontab의 소유자에게 메일을 전송한다. 

# 메일 전송을 하려면 로컬 PC에서 MTA를 설치해야 한다. 대표적으로 Postfix가 있다.
MAILTO="id@naver.com"

# 실행한 시간대 
CRON_TZ=Japan

# 시간과 데이터 필드의 의미는 다음과 같다. 
              field          allowed values
              -----          --------------
              minute         0-59
              hour           0-23
              day of month   1-31
              month          1-12 (or names, see below)
              day of week    0-7 (0 or 7 is Sunday, or use names such as sun, mon, tue)


# 매일 0시 5분에 원하는 동작을 하고 싶을 때 
5 0 * * *       $HOME/bin/daily.job >> $HOME/tmp/out 2>&1

# 매달 1일에 14시 15분에 원하는 동작을 실행하고 싶을 때
15 14 1 * *     $HOME/bin/monthly

# run at 10 pm on weekdays, annoy Joe
# 월-금 22시에 첫 번째 동작을 실행하고 
# 매일 2시간마다 매시 23분에 두 번째 동작을 실행한다.
# 일요일 4시 5분에 세 번째 동작을 실행한다. 
0 22 * * 1-5    mail -s "It's 10pm" joe%Joe,%%Where are your kids?%
23 0-23/2 * * * echo "run 23 minutes after midn, 2am, 4am ..., everyday"
5 4 * * sun     echo "run at 5 after 4 every sunday"

만약에 /home/workspace/src/example.jar 을 매분마다 실행하고 싶다면 crontab에서 아래와 같이 설정해줘야 한다.

* * * * * java -jar /home/workspace/src/example.jar 

(더 좋은 방법이 있는지는 모르겠지만) 파일을 실행할 때 절대경로를 붙여서 사용하면 확실하게 실행된다.
더 좋은 방법을 찾으면 반영하자.

한계

위에서 설정을 보면 알겠지만 가장 작은 시간단위가 분 단위이다. 즉, 매분 n초에 실행하고 싶을 때 crontab을 사용해서 원하는 동작을 할 수는 없다.

다만, 구글링을 통해 찾아보면 sleep을 이용해서 n초마다 동작을 실행시키는 방법이 있기는 하기 때문에 이 방법이 필요하다면 검색을 통해서 알아보자.

crontab 실행 로그 ⇒ /var/log/syslog에서 확인 가능

크론탭을


++ 2023/08/17(목)

크론탭에서 python 파일이 제대로 동작하지 않는 경우

  • 로컬 PC 환경

    Distributor ID:    Ubuntu
    Description:    Ubuntu 20.04.6 LTS

크론탭을 가지고 작업을 하려고 했는데 /var/log/syslog를 통해 내가 설정한 작업들이 실행은 되지만 작업의 실행 결과가 나타나지 않은 문제가 발생했다.

  • 초기 crontab 파일

    45 * * * * java -jar /원하는경로/jar파일.jar >> /특정경로/result.log
    24 12 * * * python /원하는경로/실행파일.py >> /특정경로/result.log

어떤 문제가 발생했는지를 알기 위해서 crontabMAILTO를 추가해서 어떤 오류가 발생했는지 메일로 전송하도록 했다.

  • MAILTO를 추가한 crontab 파일

    MAILTO = "아이디@gamil.com"
    45 * * * * java -jar /원하는경로/jar파일.jar >> /특정경로/result.log
    24 12 * * * python /원하는경로/실행파일.py >> /특정경로/result.log

그랬더니 다음과 같은 오류가 메일로 전송되었다.

ModuleNotFoundError: No module named 'pandas'

분명히 로컬 PC에서는 내가 원하는 python 파일이 정상적으로 실행되었는데 crontab에서는 실행되지 않았다.

로컬 > python 원하는 파일.py ==> 정상 실행 

crontab 
24 12 * * * python /원하는경로/실행파일.py >> /특정경로/result.log  ==> 오류 발생

알고보니 로컬 PC에서 적용되는 python 버전crontab에서 적용되는 python 버전이 달라서 생긴 문제였다.
그래서 이를 해결하기 위해서 crontab의 python 버전을 아래와 같은 방법으로 맞췄다.

  • python 버전을 맞춘 crontab

    MAILTO = "아이디@gamil.com"
    45 * * * * java -jar /원하는경로/jar파일.jar >> /특정경로/result.log
    24 12 * * * /python/저장된/디렉토리/bin/python3.7 /원하는경로/실행파일.py >> /특정경로/result.log

    python bin 폴더의 저장위치는 which python을 통해 찾을 수 있다. 거기서 원하는 python 버전을 선택해서 적용하면 된다.
    나는 3.7 버전이 적용되도록 하고 싶어서 위와 같이 작성했다.

system wide crontab의 위치 : /etc/crontab 파일

수정하고 싶다면 root 권한으로 수정해야 한다. root 계정을 이용해서 접근하거나 sudo를 이용하면 된다.

PC의 전체 사용자들의 crontab 파일 관리 - root 권한이 있어야 볼 수 있음

1) root 계정으로 접속 or sudo -i를 입력해서 root 계정으로 변경
2) /var/spool/cron/crontabs에 사용자들이 설정한 crontab 파일이 존재한다.