서버 운영하다 보면 “매일 밤 2시에 백업 돌려야 하는데…”, “로그 파일 1년치가 쌓여서 디스크가 꽉 찼어요…” 같은 반복 작업이 쏟아집니다. 이걸 사람이 매번 손으로 하면 언젠가 놓치거나 잊어버려서 장애로 이어집니다. 리눅스의 cron은 이런 반복 작업을 자동 실행해 주는 가장 기본적인 도구입니다.
이 글에서는 Ubuntu 24.04 LTS 기준으로 crontab 문법, 실전 예제 10가지, 자주 하는 실수까지 정리합니다.
crontab 문법 — 5개 필드의 의미
# ┌───── 분 (0-59)
# │ ┌─── 시 (0-23)
# │ │ ┌─ 일 (1-31)
# │ │ │ ┌ 월 (1-12)
# │ │ │ │ ┌ 요일 (0-6, 0=일요일)
# │ │ │ │ │
# * * * * * 실행할 명령어
| 기호 | 의미 | 예시 |
|---|---|---|
* | 모든 값 | * * * * * — 매 분 |
, | 여러 값 나열 | 0 9,18 * * * — 오전 9시, 오후 6시 |
- | 범위 | 0 9-18 * * * — 9시~18시 매 정시 |
/ | 주기 | */5 * * * * — 5분마다 |
@reboot | 부팅 시 1회 | @reboot /path/to/start.sh |
@daily | 매일 자정 | 0 0 * * * 과 동일 |
실전 예제 10가지 (복사해서 바로 쓰기)
# 1. 매일 새벽 2시 MySQL 백업
0 2 * * * mysqldump -u root -p'PASS' wordpress | gzip > /backup/wp_$(date +\%F).sql.gz
# 2. 매주 일요일 03:00 오래된 백업 정리 (30일 지난 것)
0 3 * * 0 find /backup -name "*.sql.gz" -mtime +30 -delete
# 3. 매 5분마다 서비스 헬스체크
*/5 * * * * curl -sf https://example.com/health || /usr/local/bin/notify-slack.sh
# 4. 매시간 nginx 로그 크기 확인 (500MB 넘으면 로테이트)
0 * * * * [ $(stat -c%s /var/log/nginx/access.log) -gt 524288000 ] && logrotate -f /etc/logrotate.d/nginx
# 5. 매일 06:00 Let's Encrypt 인증서 갱신
0 6 * * * certbot renew --quiet --post-hook "systemctl reload nginx"
# 6. 매일 00:10 WP-CLI로 업데이트 확인
10 0 * * * cd /home/wpadmin/public_html && /usr/local/bin/wp plugin list --update=available > /tmp/wp-updates.txt
# 7. 매 10분마다 외부 API 데이터 수집
*/10 * * * * /usr/bin/python3 /home/wpadmin/scripts/collect_api.py >> /var/log/collect.log 2>&1
# 8. 매일 자정에 임시 파일 정리
@daily find /tmp -type f -atime +7 -delete
# 9. 매월 1일 09:00 월간 리포트 이메일
0 9 1 * * /home/wpadmin/scripts/monthly_report.sh | mail -s "월간 리포트" [email protected]
# 10. 부팅 후 10초 뒤 커스텀 데몬 실행
@reboot sleep 10 && /usr/local/bin/my-daemon start
crontab 관리 명령어
# 현재 사용자의 crontab 편집
crontab -e
# 현재 사용자의 crontab 목록 보기
crontab -l
# 전체 삭제 (주의)
crontab -r
# 다른 사용자의 crontab 관리 (root 권한 필요)
sudo crontab -u wpadmin -l
# 시스템 전역 cron 파일 위치
ls -la /etc/cron.{hourly,daily,weekly,monthly}/
cat /etc/crontab
Ubuntu에서는 cron이 기본 활성화되어 있습니다. 상태 확인:
systemctl status cron
# ● cron.service - Regular background program processing daemon
# Active: active (running) ...
⚠️ 자주 하는 실수와 해결법
1. PATH 환경변수 없음
터미널에서는 wp, node가 되는데, cron에서는 “command not found”가 뜹니다. cron은 최소 PATH만 쓰기 때문입니다. 무조건 절대경로를 사용하거나 crontab 상단에 PATH를 지정하세요.
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
0 2 * * * /usr/bin/python3 /home/me/script.py
2. 출력이 어디로 갔는지 모름
cron 작업의 stdout은 기본적으로 해당 사용자에게 로컬 메일로 전송됩니다. 메일 서버가 없으면 사라지죠. 반드시 로그 파일로 리다이렉트하세요.
# stdout + stderr 모두 로그로
0 2 * * * /home/me/backup.sh >> /var/log/backup.log 2>&1
# 완전히 버리기 (정말 필요 없을 때만)
0 2 * * * /home/me/backup.sh > /dev/null 2>&1
3. % 기호 이스케이프 누락
crontab에서 %는 특수 문자(줄바꿈으로 해석)라, date +%F 같은 표현은 깨집니다. 반드시 \%로 이스케이프하거나 스크립트 파일에 넣어 호출하세요.
4. 같은 작업이 중복 실행
5분마다 돌리는 수집 스크립트가 6분씩 걸리면 다음 실행이 겹칩니다. flock으로 잠금을 걸어 동시 실행을 방지하세요.
*/5 * * * * /usr/bin/flock -n /tmp/collect.lock /usr/bin/python3 /home/me/collect.py
5. 시간대(timezone) 문제
클라우드 인스턴스는 기본이 UTC인 경우가 많습니다. date 명령으로 확인 후 필요하면 Asia/Seoul로 변경하세요.
date # 현재 시스템 시간 확인
sudo timedatectl set-timezone Asia/Seoul
sudo systemctl restart cron # cron도 재시작 해줘야 반영
디버깅 — 내 cron이 왜 안 돌지?
- syslog 확인:
grep CRON /var/log/syslog | tail -20— 실행 시도 기록이 찍힘 - 문법 검증 도구 사용: crontab.guru에서 표현식 복붙해 확인
- 커맨드를 셸에서 먼저 실행해 보기 — 경로·권한 문제가 여기서 대부분 잡힘
- 임시로 매 분 실행:
* * * * * echo "hello" >> /tmp/cron-test.log— 최소한 cron 자체가 도는지 먼저 확인 - 사용자 권한 확인:
/etc/cron.allow에 사용자가 없고/etc/cron.deny에 있으면 차단
cron vs systemd timer — 언제 뭘 쓸까?
| 상황 | 추천 |
|---|---|
| 간단한 반복 작업, 빠르게 설정 | cron |
| 실패 시 자동 재시도·의존성 관리 필요 | systemd timer |
| 실행 로그를 journalctl로 관리 | systemd timer |
| 컨테이너 안에서 돌림 | 호스트의 cron or 앱 내 스케줄러 |
| 초 단위 정밀 제어 필요 | systemd timer (OnCalendar=*:0/30) |
FAQ
Q. Windows에도 cron이 있나요?
Windows는 작업 스케줄러(Task Scheduler)가 동일한 역할을 합니다. WSL을 쓰면 Ubuntu 안에서 cron을 그대로 쓸 수 있지만, WSL 세션이 켜져 있을 때만 동작합니다.
Q. WordPress는 wp-cron이 따로 있다는데?
WordPress의 wp-cron.php는 방문자가 페이지를 열 때마다 실행되는 가상 크론입니다. 트래픽이 적으면 예약 작업이 밀립니다. 실제 운영에서는 wp-cron을 꺼 두고 시스템 cron으로 호출하는 방식을 권장합니다.
# wp-config.php
define('DISABLE_WP_CRON', true);
# crontab
*/10 * * * * curl -s https://example.com/wp-cron.php?doing_wp_cron > /dev/null 2>&1
Q. 특정 날짜 하루만 실행하고 싶어요.
cron은 반복 작업에 특화되어 있어 일회성에는 부적합합니다. 대신 at 명령을 쓰세요.
echo "/home/me/deploy.sh" | at 03:00 2026-05-01
마무리
cron의 어려움은 문법보다 환경 차이(PATH, timezone, 권한)에서 옵니다. 새 작업을 등록했을 때는 반드시 (1) 셸에서 직접 실행해 먼저 성공시키고, (2) 로그를 파일로 떨어뜨리고, (3) /var/log/syslog에서 실제 실행 여부를 확인하는 3단계를 습관화하세요. 이것만 지켜도 “왜 안 돌지?” 삽질 시간이 절반으로 줄어듭니다.