cron 표현식이란?
cron 표현식은 압축된 일정표다. 공백으로 나뉜 다섯 필드 — 분, 시, 일, 월, 요일 — 가 함께 언제 작업이 돌지를 적는다. cron 은 1분마다 이것을 읽어 모든 필드가 지금 시각과 맞으면 작업을 시작한다.
문법이 빽빽해서 글자 하나가 틀려도 그럴듯해 보이는 일정이 만들어지고, 엉뚱한 시각에 도는 것을 몇 주 뒤에야 알아채는 일이 생긴다. 이 도구는 표현식을 문장으로 되돌리고 다음 다섯 번의 시각을 늘어놓는다. 배포한 뒤가 아니라 배포하기 전에 확인하라고.
The time and date fields are: minute 0-59, hour 0-23, day of month 1-31, month 1-12, day of week 0-7 (0 or 7 is Sunday).
기능
- 말로 옮긴다
- 표현식을 문장으로 보여준다 — "오전 09:00, 월요일부터 금요일까지". 필드 순서를 외우고 있는 사람이 있어야만 검토할 수 있는 상태를 벗어난다.
- 다음 다섯 번의 실행 시각
- 설명을 읽는 것과 동작을 확인하는 것은 다르다. 다음 다섯 번을 실제로 계산해 내 시간대로 보여준다. 설명만으로는 가려지는 하나 차이의 실수가 여기서 걸린다.
- 필드별로 갈라 본다
- 다섯 필드에 각각 이름을 붙인다. 가장 흔한 혼동 — 일과 요일이 둘 다 있고, 둘 다 지정하면 둘 중 하나만 맞아도 실행된다는 것 — 이 여기서 풀린다.
- 여섯 필드 실수를 잡는다
- Quartz 와 Spring 은 맨 앞에 초 필드를 받지만 표준 crontab 은 받지 않는다. 여섯 필드짜리 표현식을 조용히 잘못 읽는 대신 표시한다.
- 페이지 밖으로 나가지 않는다
- 일정은 브라우저에서 계산된다. 표현식도, 그 인프라가 무엇을 돌리는지에 대한 힌트도 어디로도 보내지 않는다.
사용법
- 1
표현식을 붙여넣는다
0 9 * * 1-5 같은 다섯 필드 표현식을 넣거나, 자주 쓰는 주기에서 고른다.
- 2
문장을 읽는다
입력 바로 아래에 표현식을 말로 옮긴 문장이 나온다.
- 3
다음 다섯 번을 확인한다
실제 실행 시각이 의도한 것과 맞는지 내 시간대로 확인한다.
- 4
필드 분해를 본다
필드마다 이름이 붙어 있어 값이 엉뚱한 자리에 들어간 것이 바로 보인다.
두 번 오는 시각과, 오지 않는 시각
cron 은 벽시계 시각에 맞춰 돈다. 그런데 서머타임이 있는 곳에서 벽시계 시각은 이어져 있지 않다. 봄 전환에는 현지 시각이 01:59 에서 03:00 으로 뛰므로 0 2 * * * 로 잡은 작업은 그날 그냥 돌지 않는다. 가을 전환에는 02:00 이 두 번 오고, 구현에 따라 한 번 돌거나 두 번 돈다. Vixie cron 은 건너뛴 작업을 밀어 주지만 많은 컨테이너 스케줄러는 그러지 않는다.
믿을 만한 해법은 따져 보는 것이 아니라 모호함을 없애는 것이다. 스케줄러를 UTC 로 돌리거나, 전환 구간을 아예 피한다 — 현지 시각 01:00~03:00 사이에는 아무것도 두지 않는다. 한 가지 더, 이 표현식의 필드는 이식 가능한 다섯 개다. 예제에서 자주 보이는 L(마지막)·W(평일)·#(n번째 요일) 문자는 Quartz 확장이고 crontab 은 거부한다.
자주 묻는 질문
다섯 필드는 각각 무엇인가?
순서대로 분(0–59), 시(0–23), 일(1–31), 월(1–12), 요일(0–7, 0과 7이 모두 일요일)이다. 별표는 모든 값, 슬래시는 간격(*/5 는 5마다), 하이픈은 범위, 쉼표는 목록을 뜻한다.
5분마다 돌리려면?
*/5 * * * * — 매시간의 5분 간격마다. 등록한 시점에서 5분 뒤가 아니라 정시에 맞춰 :00, :05, :10 에 실행된다는 점에 주의한다.
작업이 예상보다 자주 돈다
일과 요일을 둘 다 * 이 아닌 값으로 지정한 경우가 거의 전부다. 그때 cron 은 둘 다가 아니라 둘 중 하나만 맞아도 실행한다 — 0 0 1 * 1 은 매월 1일에도 돌고 매주 월요일에도 돈다.
어떤 도구가 쓰는 여섯 번째 필드는?
초다. Quartz, Spring 의 @Scheduled, 일부 클라우드 스케줄러가 맨 앞에 초 필드를 받아 모두 여섯 필드가 된다. 표준 유닉스 crontab 은 다섯이고 여섯을 거부한다. Spring 설정에서 복사한 표현식이 crontab 에서 실패하는 이유다.
cron 은 어느 시간대를 쓰나?
스케줄러를 따로 설정하지 않았다면 실행하는 기계의 시스템 시간대다. 컨테이너는 대개 UTC 로 뜨는데 개발자는 현지 시각으로 생각한다. 이 페이지가 다음 실행 시각을 내 시간대로 보여주는 것은 그 차이를 눈에 보이게 하려는 것이다.
@daily 나 @reboot 도 쓸 수 있나?
그것은 crontab 의 축약어이지 다섯 필드 표현식 문법의 일부가 아니다. @daily 는 0 0 * * *, @hourly 는 0 * * * * 와 같고, @reboot 는 시각이 아니라 부팅으로 촉발되므로 대응하는 표현식이 아예 없다.
여기서 막힌다면
이 도구가 따르는 규격
- crontab(5) — 리눅스 매뉴얼 — 필드 정의, 간격·범위 문법, 그리고 일과 요일이 OR 로 묶이는 규칙.
- POSIX.1-2024 — crontab 유틸리티 — 이식 가능한 다섯 필드 형식. 표준 crontab 이 받는 것.
- Quartz — CronTrigger 튜토리얼 — 초와 연도가 붙는 여섯·일곱 필드 방언, 그리고 그것이 crontab 으로 옮겨가지 않는 이유.