본문 바로가기
개발환경/우분투

우분투 작업 스케줄러 Crontab 사용법, 디버깅, 주의 사항

by Kibua20 2020. 7. 17.

우분투에서 프로그램을 예약 실행해야 하는 경우 crontab 사용할 수 있습니다.  예를 들어 1시간 마다 특정 폴더를 백업하거나 Git 소스를 업데이트는 하는 자동화 작업을 진행하는 경우 crontab을 활용하면 됩니다.  crontab은 프로세스 예약 데몬이며, 리눅스용 작업 스케줄러로 특정 시각에 명령어를 수행하도록 등록 가능합니다.  

출처: https://www.youtube.com/watch?v=llUw3RtD-Yw

 

crontab 명령어 사용 방법

$  crontab [ -u user ] [ -i ] { -e | -l | -r }
   -e (edit user's crontab)   # 예약 작업 추가 
   -l (list user's crontab)  # 예약 작업 리스트 확인 
   -r (delete user's crontab) # 예약 작업 삭제 
   -i (prompt before deleting user's crontab)


사용자 계정의 예약 명령어 사용 방법 

$ crontab -e   # 명령어 추가 

#Editor에서 양식으로 수행항 명령어를 작성합니다.  * 이 5개이고 각 항목은 분/시/일/월/요일입니다.  

 

* * * * *  수행할 명령어
┬ ┬ ┬ ┬ ┬
│ │ │ │ └─ 요일 (0 - 6) (0:일요일, 1:월요일, 2:화요일, …, 6:토요일)
│ │ │ └─ 월 (1 - 12)
│ │ └─일 (1 - 31)
│ └─ 시 (0 - 23)
└─ 분 (0 - 59)

 

* * * * * /root/backup.sh
매분, 매시간, 매일, 매월, 매일, 즉 1분마다 /root/backup.sh를 실행


0 4 * * * /root/backup.sh
0분, 4시, 매일, 매월, 매일, 즉 매일 4시에 /root/backup.sh를 실행


0 4 * * 1-5 /root/backup.sh
0분, 4시, 매일, 매월, 월요일부터 금요일, 즉 평일 4시에 /root/backup.sh를 실행


*/10 4 * * * /root/backup.sh
10분 간격, 4시, 매일, 매월, 매일, 즉 매일 4시, 4시 10분, 4시 20분, 4시 30분, 4시 40분, 4시 50분에 /root/backup.sh를 실행


0 */6 * * * /root/backup.sh
6시간마다 /root/backup.sh를 실행

 

0 8 * * 1-5 /root/weekday.sh

평일(월요일~금요일) 08:00 에 /root/weekday.sh 실행

 

0 8 * * 0,6 /root/weekend.sh

→ 주말(일요일, 토요일) 08:00 에 /root/weekend.sh 실행

 

0 5 * * * /sbin/shutdown -r now
→ 매일 새벽 5시에 재부팅하기

 

 


Crontab 동작 확인

crontab 서비스 status 확인, 가동, 재가동

$ service cron status     # 동작 여부 확인

$ service cron start        # 가동
$ service cron restart   # 재가동

 

$ service cron status를 확인하면 아래와 같이 crontab 등록 결과를 보여줍니다.

● cron.service - Regular background program processing daemon
     Loaded: loaded (/lib/systemd/system/cron.service; enabled; vendor preset: enabled)
     Active: active (running) since Fri 2020-07-17 20:35:57 KST; 1h 1min ago
       Docs: man:cron(8)
   Main PID: 1148 (cron)
      Tasks: 1 (limit: 9363)
     Memory: 1.3M
     CGroup: /system.slice/cron.service
             └─1148 /usr/sbin/cron -f

 7월 17 20:35:57 ubuntu-pc systemd[1]: Started Regular background program processing daemon.
 7월 17 20:35:57 ubuntu-pc cron[1148]: (CRON) INFO (pidfile fd = 3)
 7월 17 20:35:57 ubuntu-pc cron[1148]: (CRON) INFO (Running @reboot jobs)
 7월 17 21:17:01 ubuntu-pc CRON[10107]: pam_unix(cron:session): session opened for user root by (uid=0)
 7월 17 21:17:01 ubuntu-pc CRON[10116]: (root) CMD (   cd / && run-parts --report /etc/cron.hourly)
 7월 17 21:17:01 ubuntu-pc CRON[10107]: pam_unix(cron:session): session closed for user root
 7월 17 21:30:01 ubuntu-pc CRON[10703]: pam_unix(cron:session): session opened for user root by (uid=0)
 7월 17 21:30:01 ubuntu-pc CRON[10703]: pam_unix(cron:session): session closed for user root

 

Crontab 로그 확인 (디버깅에 필요)

$ cat /var/log/syslog | grep CRON

Jul 17 21:17:01 ubuntu-pc CRON[10116]: (root) CMD (   cd / && run-parts --report /etc/cron.hourly)
Jul 17 21:30:01 ubuntu-pc CRON[10704]: (root) CMD ([ -x /etc/init.d/anacron ] && if [ ! -d /run/systemd/system ]; then /usr/sbin/invoke-rc.d anacron start >/dev/null; fi)

로그 저장 script

crontab은 백그라운드로 실행되기 때문에 프로그램에서 출력하는 로그가 화면에 나오지 않아 로그로 저장해야 합니다. 

 

[test.sh]

#! /bin/bash --login

/kibua/crontabjoa.sh  2 > &1  | tee logfile.txt

 

#2>&1는  표준 출력에서 표준 에러(stderr)도 표준 출력(stdout)으로 보내는 명령어입니다. 표준 입출력은 여기를 참고하세요.

프로그램 동작 시 exception과 같은 에러는 stderr에 출력하기 때문에 디버깅을 하는 경우 2>&1을 꼭 추가하세요. 


 

시스템 레벨의 명령어 추가 방법

시스템 레벨에서 crontab 명령어는 /etc/crontab 에서 가능합니다.  /etc/crontab 파일의 내용을 보면 이미 cron.daily cron.weekly, cron.monthly가 실행되고 있습니다.  아주 특별한 일 아니면 앞에서 설명한 사용자 계정으로 등록하는 것이 안전합니다. 

 

$ vi /etc/crontab 

 

# /etc/crontab: system-wide crontab
# Unlike any other crontab you don't have to run the `crontab'
# command to install the new version when you edit this file
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.

SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

17 * * * * root cd / && run-parts --report /etc/cron.hourly
25 6 * * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6 * * 7 root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6 1 * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )


관리자 권한으로 Crontab 추가 

$ sudo crontab -e

 

# 꼭 필요한 경우가 아니면 sudo 권한은 사용은 자제하고, 사용해야 하는 경우 Permission과 환경 변수를 체크해야 합니다.


주의해야 사항 

1. 실행 파일의 Permission 체크 

 다른 계정의 script을 접근하거나,   bash shell script 또는 python 파일을 바로 실행할 때 실행 권한이 반드시 있어야 합니다. 

     $ chmod 766 test.sh

 

2. 로그인 환경 변수 

crontab은  보안 이슈때문에   bashrc와 profile을 실행하지 않는다고 합니다. bashrc 파일에 export JAVA_HOME이나 특정 path를 환경 변수를 추가한 경우에는 주의해야 합니다.  각 계정의 환경 변수를 실행하는 방법은 bash 실행 시 --login 옵션을 추가하면 각 계정의 bashrc에서 정의한 환경 변수를 처리합니다.  참고로 로그인 셀 bashrc에 대한  참고 하세요. 링크

 

[test.sh]

#! /bin/bash --login

/kibua/crontab_job.sh 

 

3. 상대 경로보다는 절대 경로를 실행

bash script이나 python script에서 현재 경로를 얻어서 getcwd() 처리하고 상대 경로로 처리하는 경우 파일 경로 에러가 있을 수 있습니다.  script에서도 cd 명령어나 chdir 명령도 실행이 되기는 하지만 코드상에서 절대 경로 기준으로 코딩을 하는 경우 에러를 줄일 수 있습니다.

 


Python 파일을 crontab 등록

[crontab 등록]

$ crontab -e 

# vi editor에서 test.py 실행 

* * * * *  /home/your/path/test.py 2>&1  | tee logfile.txt

* * * * * python  /home/your/path/test2.py 2>&1  | tee logfile.txt

 

[test.py]

#!/usr/bin/python3    -     #Py 파일 최상단에 인터프리터가 지정되어 있어야 합니다.

# -*- coding: utf-8 -*-

print ('crontab test')

 

<관련 글>

[모바일/Python] - Python 표준 입출력(stdin/stdout) 활용 - 리눅스 프로그램과 연동

[모바일/Python] - Python: 폴더 백업 기능 구현 (7zip 압축, Sample code)

[개발환경] - 우분투에서 7zip command line 사용하기 (p7zip과 7za추천)

[모바일/Python] - Python 에러: /usr/bin/env: `python3\r': 그런 파일이나 디렉터리가 없습니다

[모바일/REST API] - Google Gmail API 사용 방법 (1) - Sample code

[모바일/Python] - Python JSON 사용 시 TypeError: Object of type bytes is not JSON serializable

[모바일/Python] - Python 2.7과 3.8호환성: a bytes-like object is required, not 'str'에러 수정

[개발환경] - 윈도우용 MobaXterm - SSH 및 X-Server 지원




댓글4