cron은 리눅스에서 정해진 시간에 반복 작업을 실행하는 스케줄러입니다. 백업, 로그 정리, 모니터링, 인증서 갱신 등 수많은 서버 자동화 작업에 활용됩니다.

crontab 기본 사용법

# 현재 사용자의 crontab 편집
crontab -e

# 현재 사용자의 crontab 목록 확인
crontab -l

# crontab 삭제 (주의: 모두 삭제)
crontab -r

# 특정 사용자의 crontab 편집/확인 (root만 가능)
sudo crontab -u username -e
sudo crontab -u username -l

시간 표현식 문법

분  시  일  월  요일  실행할명령어
*   *   *   *   *     command
│   │   │   │   └─ 요일 (0=일요일, 1=월요일, ..., 6=토요일, 7=일요일)
│   │   │   └──── 월 (1~12)
│   │   └──────── 일 (1~31)
│   └──────────── 시 (0~23)
└──────────────── 분 (0~59)

특수 표현

표현 의미
* 모든 값
*/5 5마다 (5분마다, 5시간마다)
1-5 1부터 5까지 (월~금요일)
1,15 1일과 15일
@reboot 부팅 시 1회
@daily 매일 자정 (0 0 * * *)
@weekly 매주 일요일 자정
@monthly 매월 1일 자정

자주 쓰는 예제

# 매 5분마다 실행
*/5 * * * * /opt/monitor.sh

# 매일 새벽 3시에 실행
0 3 * * * /opt/backup.sh

# 매주 월요일 오전 9시에 실행
0 9 * * 1 /opt/weekly-report.sh

# 평일(월~금) 오전 8시에 실행
0 8 * * 1-5 /opt/workday.sh

# 매월 1일, 15일 실행
0 0 1,15 * * /opt/billing.sh

# 매 시간 정각에 실행
0 * * * * /opt/hourly.sh

# 부팅 시 1회 실행
@reboot /opt/startup.sh

# 매일 자정 (축약)
@daily /opt/daily-cleanup.sh

시스템 cron vs 사용자 crontab

사용자 crontab (crontab -e)

  • 특정 사용자 권한으로 실행
  • 분 시 일 월 요일 명령어 형식

시스템 cron (/etc/cron.d/, /etc/crontab)

  • 사용자 지정 가능 (루트 권한 필요)
  • 분 시 일 월 요일 사용자 명령어 형식 (사용자 필드 추가)
# /etc/cron.d/myapp
0 3 * * * root /opt/backup.sh >> /var/log/backup.log 2>&1
0 2 * * * www-data /opt/cleanup.sh

시스템 cron 디렉터리

ls /etc/cron.daily/    # 매일 실행
ls /etc/cron.weekly/   # 매주 실행
ls /etc/cron.monthly/  # 매월 실행
ls /etc/cron.hourly/   # 매시간 실행

# 스크립트를 해당 디렉터리에 넣으면 자동 실행 (실행 권한 필요)
sudo cp myscript.sh /etc/cron.daily/
sudo chmod +x /etc/cron.daily/myscript.sh

환경 변수와 PATH 문제

cron 실행 환경은 일반 쉘과 다릅니다. PATH가 제한되어 있어 명령을 찾지 못하는 경우가 많습니다:

# crontab에서 PATH 명시적 설정
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

0 3 * * * /opt/backup.sh

# 또는 스크립트에서 절대 경로 사용
/usr/bin/mysqldump -u root mydb > /backup/db.sql
/usr/local/bin/python3 /opt/script.py

로그 출력 제어

# 표준 출력과 오류를 모두 로그 파일에 저장
0 3 * * * /opt/backup.sh >> /var/log/backup.log 2>&1

# 오류만 로그 파일에 저장 (표준 출력 버림)
0 3 * * * /opt/backup.sh > /dev/null 2>> /var/log/backup-error.log

# 모든 출력 버리기 (메일 발송도 없음)
0 3 * * * /opt/backup.sh > /dev/null 2>&1

# MAILTO 설정 (이메일로 출력 전송, 빈 문자열이면 발송 안 함)
MAILTO=""
0 3 * * * /opt/backup.sh

cron 실행 로그 확인

# Ubuntu/Debian
sudo grep CRON /var/log/syslog | tail -20

# CentOS/RHEL
sudo grep CRON /var/log/cron | tail -20

# journalctl (systemd)
sudo journalctl -u cron -n 50 --no-pager

실전 cron 예제 모음

# 매일 새벽 3시 MySQL 백업
0 3 * * * mysqldump -u root -p비밀번호 --all-databases | gzip > /backup/mysql_$(date +\%Y\%m\%d).sql.gz

# 매일 새벽 4시 30일 이상된 백업 파일 삭제
30 4 * * * find /backup -name "*.sql.gz" -mtime +30 -delete

# 매시간 디스크 사용량 확인
0 * * * * df -h >> /var/log/disk-usage.log

# 매일 자정 Nginx 로그 로테이트
0 0 * * * kill -USR1 $(cat /var/run/nginx.pid) && sleep 1 && mv /var/log/nginx/access.log /var/log/nginx/access_$(date +\%Y\%m\%d).log

# 5분마다 서비스 상태 체크
*/5 * * * * systemctl is-active nginx > /dev/null || systemctl restart nginx

# 매월 1일 Let's Encrypt 인증서 갱신 시도
0 0 1 * * certbot renew --quiet

# 부팅 시 VPN 재연결
@reboot sleep 30 && /usr/local/bin/wg-quick up wg0

cron 작업 디버깅

# cron이 실행하는 것과 같은 환경에서 수동 실행
env -i HOME=/root SHELL=/bin/bash PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin /opt/backup.sh

# cron 서비스 상태 확인
sudo systemctl status cron

# cron 데몬 재시작
sudo systemctl restart cron

cron을 잘 활용하면 서버 관리 업무의 상당 부분을 자동화할 수 있습니다. 중요한 자동화 작업은 로그를 남겨 정상 실행 여부를 정기적으로 확인하는 습관을 들이세요.