Cron과 같은 프로그램 실행 설정 방법

(2020. 12. 09 일 업데이트)

라즈베리파이에서 원하는 작업을 스케쥴 예약 등록 해봅시다. 리눅스 cron 프로그램을 사용하면, 다양한 조건으로 작업을 예약 등록할 수 있습니다. cron을 잘 사용하면, 여러가지 일을 자동화시킬 수 있습니다.

cron과 crontab은 리눅스 모든 패키지에 거의 기본으로 포함되어있습니다. 라즈베리파이에도 기본으로 포함되어 있습니다. cron은 특정 명령어나 스크립트를 예약 동작시켜 주는 프로그램입니다. cron이 시스템 시간을 주기적으로 확인하여, 설정된 명령어를 실행시켜주는 역할을 하고, 이때 시간 설정은 crontab 프로그램을 사용하여 하게 됩니다. 즉, cron은 명령어들을 정해진 시간에 실행시켜 주는 일을 하고, crontab은 사용자가 명령어를 등록/관리하는 창구 역할을 합니다.

crontab을 여러가지 작업을 다양한 시간 옵션으로 예약 등록할 수 있습니다. 예를 들면, 매주 일요일 새벽 2시에 SSD의 파일을 HDD로 백업하는 작업을 하거나, 평일(월~금)에 매일 아침 7시에 재고 엑셀 파일을 검색해서 오늘 확인해야할 아이템들을 검색하는 작업을 할 수 있습니다. 라즈베리파이 경우는 카메라를 달아서 매일 8시부터 10시 사이에 매 분 단위로 사진을 촬영하는 스케쥴 설정등이 가능합니다.

cron에 스케쥴 작업을 등록하려면, crontab 명령어를 사용합니다. crontab 명령어는 현재 로그인 유저 id를 기반으로 설정내용을 저장합니다. pi 계정으로 crontab을 설정하면 pi 계정에 저장이 됩니다. 아래와 같은 옵션으로 사용합니다.

현재 crontab에 저장된 스케쥴 작업 내용 확인 옵셥

pi@raspberrypi:~ $ crontab -l

pi@raspberrypi:~ $ crontab -e

crontab 작업 내용 모두 삭제(현재 유저 설정 내용 삭제)

pi@raspberrypi:~ $ crontab -r

crontab -l 옵션으로 현재 설정된 내용을 자세히 살펴보겠습니다. # 으로 시작하는 줄은 주석처리가 된것으로 코멘트의 역할만 합니다.

pi@raspberrypi::~ $ crontab -l # Edit this file to introduce tasks to be run by cron. # # Each task to run has to be defined through a single line # indicating with different fields when the task will be run # and what command to run for the task ... # For more information see the manual pages of crontab(5) and cron(8) # # m h dom mon dow command @reboot date > /home/pi/.log/crontab.txt */10 * * * * python3 /home/pi/.localbin/torrent_crawler.py >> /home/pi/.log/torrent_crawler.txt 2>&1 0 4 * * * python3 /home/pi/.localbin/clean_up_olders.py pi@raspberrypi::~ $

아래 부분에 # 표시가 되어 있지 않은 라인들이 실제 스케쥴 예약 작업이 등록된 명령어들입니다. m h dom mon dow command 가 있는 라인을 보세요. 순서대로 분(0-59), 시(0-24), 일(1-31), 월(1-12), 요일(0-7), 그리고 등록할 명령어를 의미합니다. 각 항목에 해당하는 숫자를 기입하던지, 모든 것을 의미하는 * 를 기입합니다.

여러가지 예제를 보는 것이 이해하는데 도움이 될 것입니다.

# 매분 run.sh 실행(기본 단위가 분임) * * * * * /home/pi/.localbin/run.sh

# 매 20분마다 run.sh 를 실행 */10 * * * * /home/pi/.localbin/run.sh

# 매주 수요일 오전 5시 15분에 run.sh 를 실행 15 5 * * 3 /home/pi/.localbin/run.sh

요일(dow)은 일요일(0)~일요일(7) 범위로 입력가능합니다. 일요일(0), 월요일(1), 화요일(2), 수요일(3), 목요일(4), 금요일(5), 토요일(6), 일요일(7) 입니다.

# 매일 매시 10분, 30분, 50분에 run.sh 를 실행 10,30,50 * * * * /home/pi/.localbin/run.sh

# 매일 1시 0분부터 20분까지 매분 run.sh 를 실행 0-20 1 * * * /home/pi/.localbin/run.sh

# 부팅 시 run.sh 를 실행 @reboot /home/pi/.localbin/run.sh > /home/pi/.log/crontab.txt

라즈베리파이에서 사용할때 도움될 사용팁입니다.

3.1 sudo 권한이 필요할때는 sudo crontab으로 설정

위에서 crontab 명령어는 현재 로그인 유저 id를 기반으로 설정내용을 저장한다고 했습니다. sudo 권한이 필요한 작업은 sudo crontab 명령어로 저장을 하여야 합니다. 아래처럼 crontab 실행을 sudo로 하면, sudo 권한을 가진채로 스크립트를 실행하게 됩니다. 예약 작업할 스크립트가 sudo 권한이 필요한 경우, 이를 사용하세요. sudo 권한의 설정 내용을 조회하려면 역시 sudo crontab -l 로 확인하여야 합니다.

pi@raspberrypi:~ $ sudo crontab -e

3.2 crontab 설정 명령어 로그 남기기

예약 작업할 스크립트가 제대로 동작하지 않는 것으로 보이면, 로그를 남겨서 실행 내역을 살펴볼 필요가 있습니다. 그때는 아래처럼 로그를 남겨서 확인할 수 있습니다. 아래 예제는 >개 2개입니다. 로그 파일을 삭제하지 않고 계속 쌓는 표현입니다. 로그 파일을 새로 생성하려면 >를 1개 사용하여야 합니다.

* * * * * /home/pi/.localbin/run.sh >> /home/pi/.log/run.log 2>&1

로그가 필요없는 경우는 null 노드에 버리면 됩니다.

* * * * * /home/pi/.localbin/run.sh > /dev/null 2>&1

3.3 부팅시 예약작업 지연 주기

부팅시 작업은 @reboot으로 기재하면 됩니다. 라즈베리파이에 ssd와 같은 외부 장치에 접근하는 스케쥴 설정을 하였다면 동작을 안하는 경우가 발생합니다. 여러 테스트를 해봤더니, 부팅후 ssd(또는 hdd)를 마운트하는 타이밍이 더 늦어서 발생합니다. crontab이 스크립트를 실행할 시점에 ssd 마운트가 되어있지 않은 것이 문제입니다. 아래와같이 sleep 시간을 살짝 주면 ssd 장치 접근에 문제가 없습니다.

@reboot sleep 10 && date > /home/pi/ssd_drive/date_log.txt

3.4 crontab 설정내용 자동 백업하기

crontab 설정에 아래와같이 crontab 설정을 파일로 백업하게 할 수 있습니다. 백업파일을 git 같은 버전관리툴을 사용하면 이력 추적까지 가능해집니다.

@reboot crontab -l > /home/pi/.localbin/crontab.backup

3.5 crontab 환경 변수 설정

cron 명령어는 설정된 명령어를 실행할때, .bashrc와 .bash_profile 파일을 로드하지 않습니다. 따라서 미리 설정한 사용자 환경변수들이 로드되지 않아서 문제가 발생하기도 합니다. 즉, shell에서는 정상적으로 실행되는 스크립트가 crontab에 등록해서 실행하면 문제가 발생하는 경우죠.

문제가 되는 경우는, 실행하는 스크립트 파일 안에서 .bashrc 파일을 직접 로드하거나 스크립트 첫 라인에 #!/bin/bash –login 옵션을 기재하여 초기화파일을 로드하게끔 설정합니다.

3.6 crontab 파일 편집시 editor 선택

crontab 파일을 만드는 가장 간단한 방법은 crontab -e 명령을 사용하는 것입니다. 이 명령은 시스템 환경에 설정된 텍스트 편집기를 호출합니다. 시스템 환경의 기본 편집기는 EDITOR 환경 변수에 정의됩니다. 이 변수가 설정되지 않은 경우 crontab 명령이 기본 편집기인 ed를 사용합니다. 가급적 잘 아는 편집기를 선택해야 합니다.

다음 예는 편집기가 정의되었는지 확인하는 방법과 vi를 기본값으로 설정하는 방법을 보여줍니다.

$ which $EDITOR $ $ EDITOR=vi $ export EDITOR

crontab 파일을 만들 때 /var/spool/cron/crontabs 디렉토리에 자동으로 놓이고 사용자 이름이 부여됩니다. 수퍼유저 권한이 있는 경우 다른 사용자 또는 root에 대해 crontab 파일을 만들거나 편집할 수 있습니다.

만약 매번 위 EDITOR 변경이 귀찮다면, .bashrc 등에 아래의 내용을 기재해 주면 됩니다. (nano or vim)

export VISUAL=nano export VISUAL=vim

Cron과 같은 프로그램 실행 설정 방법

crontab 상태정보 알아보기 + stop & start

$systemctl status cron

pi@raspberrypi:~/workspace/crawling_shopee_boost $ systemctl status cron ● cron.service - Regular background program processing daemon Loaded: loaded (/lib/systemd/system/cron.service; enabled; vendor preset: enabled) Active: active (running) since Wed 2020-12-09 22:44:24 JST; 27min ago Docs: man:cron(8) Main PID: 24910 (cron) Tasks: 126 (limit: 4915) CGroup: /system.slice/cron.service ├─24910 /usr/sbin/cron -f ├─25608 /usr/sbin/CRON -f ├─25609 /bin/sh -c /home/pi/rpi-sync/rclone-sync-crawling-daumcafe_all.sh > /dev/null 2>&1 ├─25610 /bin/bash /home/pi/rpi-sync/rclone-sync-crawling-daumcafe_all.sh ├─25631 /usr/bin/rclone copy -v hdd_storage/crawling_downloaded_all crawlingcafe_drive_all: ├─25856 /usr/lib/chromium-browser/chromedriver --port=51359 ├─25864 /usr/lib/chromium-browser/chromium-browser-v7 --disable-quic --enable-tcp-fast-open --ppapi-flash-path=/usr/lib/chrom ├─25888 /usr/lib/chromium-browser/chromium-browser-v7 --type=zygote --no-zygote-sandbox --no-sandbox --enable-logging --headl ├─25889 /usr/lib/chromium-browser/chromium-browser-v7 --type=zygote --no-sandbox --enable-logging --headless --log-level=0 -- ├─25902 /usr/lib/chromium-browser/chromium-browser-v7 --type=gpu-process --field-trial-handle=1778091407555898586,36595157604 ├─25905 /usr/lib/chromium-browser/chromium-browser-v7 --type=utility --utility-sub-type=network.mojom.NetworkService --field- ├─25931 /usr/lib/chromium-browser/chromium-browser-v7 --type=renderer --no-sandbox --disable-dev-shm-usage --allow-pre-commit ├─26569 /usr/sbin/CRON -f ├─26570 /bin/sh -c /home/pi/workspace/crawling_shopee_boost/shopee_crawling_boost.sh >> /home/pi/workspace/crawling_shopee_bo ├─26571 /bin/bash /home/pi/workspace/crawling_shopee_boost/shopee_crawling_boost.sh ├─26573 python3 /home/pi/workspace/crawling_shopee_boost/shopee_crawling_boost.py ├─26576 /usr/lib/chromium-browser/chromedriver --port=39805 ├─26585 /usr/lib/chromium-browser/chromium-browser-v7 --disable-quic --enable-tcp-fast-open --ppapi-flash-path=/usr/lib/chrom ├─26609 /usr/lib/chromium-browser/chromium-browser-v7 --type=zygote --no-zygote-sandbox --no-sandbox --enable-logging --headl ├─26610 /usr/lib/chromium-browser/chromium-browser-v7 --type=zygote --no-sandbox --enable-logging --headless --log-level=0 -- ├─26623 /usr/lib/chromium-browser/chromium-browser-v7 --type=gpu-process --field-trial-handle=1994713181809015455,65140469196 ├─26625 /usr/lib/chromium-browser/chromium-browser-v7 --type=utility --utility-sub-type=network.mojom.NetworkService --field- └─26650 /usr/lib/chromium-browser/chromium-browser-v7 --type=renderer --no-sandbox --disable-dev-shm-usage --allow-pre-commit 12월 09 23:04:13 raspberrypi CRON[26020]: pam_unix(cron:session): session closed for user pi 12월 09 23:06:01 raspberrypi CRON[26195]: pam_unix(cron:session): session opened for user pi by (uid=0) 12월 09 23:06:01 raspberrypi CRON[26196]: (pi) CMD (/home/pi/workspace/crawling_shopee_boost/shopee_crawling_boost.sh >> /home/pi/worksp 12월 09 23:06:46 raspberrypi CRON[26195]: pam_unix(cron:session): session closed for user pi 12월 09 23:09:01 raspberrypi CRON[26380]: pam_unix(cron:session): session opened for user pi by (uid=0) 12월 09 23:09:01 raspberrypi CRON[26381]: (pi) CMD (/home/pi/workspace/crawling_shopee_boost/shopee_crawling_boost.sh >> /home/pi/worksp 12월 09 23:10:01 raspberrypi CRON[26506]: pam_unix(cron:session): session opened for user pi by (uid=0) 12월 09 23:10:01 raspberrypi CRON[26507]: (pi) CMD (/home/pi/workspace/crawling_daumcafe/crawling_daumcafe/crawling_daumcafe_run.sh >> / 12월 09 23:12:01 raspberrypi CRON[26569]: pam_unix(cron:session): session opened for user pi by (uid=0) 12월 09 23:12:01 raspberrypi CRON[26570]: (pi) CMD (/home/pi/workspace/crawling_shopee_boost/shopee_crawling_boost.sh >> /home/pi/worksp

pi@raspberrypi:~/workspace/crawling_shopee_boost $ service cron status ● cron.service - Regular background program processing daemon Loaded: loaded (/lib/systemd/system/cron.service; enabled; vendor preset: enabled) Active: active (running) since Wed 2020-12-09 23:14:12 JST; 11min ago Docs: man:cron(8) Main PID: 26797 (cron) Tasks: 47 (limit: 4915) CGroup: /system.slice/cron.service ├─25856 /usr/lib/chromium-browser/chromedriver --port=51359 ├─25864 /usr/lib/chromium-browser/chromium-browser-v7 --disable-quic --enable-tcp-fast-open --p ├─25888 /usr/lib/chromium-browser/chromium-browser-v7 --type=zygote --no-zygote-sandbox --no-sa ├─25889 /usr/lib/chromium-browser/chromium-browser-v7 --type=zygote --no-sandbox --enable-loggi ├─25902 /usr/lib/chromium-browser/chromium-browser-v7 --type=gpu-process --field-trial-handle=1 ├─25905 /usr/lib/chromium-browser/chromium-browser-v7 --type=utility --utility-sub-type=network ├─25931 /usr/lib/chromium-browser/chromium-browser-v7 --type=renderer --no-sandbox --disable-de └─26797 /usr/sbin/cron -f 12월 09 23:17:01 raspberrypi CRON[26893]: pam_unix(cron:session): session opened for user root by (uid=0) 12월 09 23:17:01 raspberrypi CRON[26894]: (root) CMD ( cd / && run-parts --report /etc/cron.hourly) 12월 09 23:17:01 raspberrypi CRON[26893]: pam_unix(cron:session): session closed for user root 12월 09 23:18:31 raspberrypi CRON[25608]: pam_unix(cron:session): session closed for user pi 12월 09 23:20:01 raspberrypi CRON[26972]: pam_unix(cron:session): session opened for user pi by (uid=0) 12월 09 23:20:01 raspberrypi CRON[26974]: (pi) CMD (/home/pi/rpi-sync/rclone-sync-crawling-daumcafe.sh > / 12월 09 23:20:23 raspberrypi CRON[26972]: pam_unix(cron:session): session closed for user pi 12월 09 23:25:01 raspberrypi CRON[27147]: pam_unix(cron:session): session opened for user pi by (uid=0) 12월 09 23:25:01 raspberrypi CRON[27148]: (pi) CMD (/home/pi/workspace/crawling_daumcafe/crawling_daumcafe 12월 09 23:26:04 raspberrypi CRON[27147]: pam_unix(cron:session): session closed for user pi

crontab -e 로 보통 내용을 변경해 주면 아래와 같이 서비스를 재시작해 주면 좋다

$service cron stop

$service cron start

#라즈베리파이Cron #cron #raspberrypi #crontab #반복작업