03 / 가이드
놀라움을 일으키지 않는 Cron 표현식 작성하기
다섯 필드와 범위, 이름 대 숫자, 일-요일 OR 함정, 일요일은 0인가 7인가, 서머타임의 공백과 중복, 그리고 배포 전 다음 실행 미리보기로 검증하는 방법.
다섯 필드, 왼쪽에서 오른쪽으로 읽기
고전적인 cron 표현식은 공백으로 구분된 다섯 필드입니다. 분(0–59), 시(0–23), 일(1–31), 월(1–12), 요일(0–7). 각 필드는 단일 값, 쉼표로 구분된 목록, 하이픈 범위, 슬래시 뒤의 스텝, 또는 모든 값을 뜻하는 별표를 받습니다.
cron 버그의 대부분은 희귀한 문법이 아니라 평범한 필드를 부주의하게 읽은 것입니다. 범위 경계에서 리셋되는 스텝이나, 23까지 세는 시스템에서 12시간제로 쓰인 시 필드 같은 것입니다.
- 목록목록은 이산 값을 고릅니다. 분 필드의 0,30은 매시 정각과 30분에 발화합니다.
- 범위와 스텝범위는 구간을 고릅니다. 시 필드의 9-17은 업무 시간을 커버하고, 스텝은 그것을 성기게 합니다. 9-17/2는 구간 안에서 두 시간마다 발화합니다.
- 별표는 전부 일치별표는 “이 필드를 무시”가 아닙니다. 모든 값에 능동적으로 일치하며, 두 날짜 필드가 상호작용하는 순간 중요해집니다.
이름은 문서가 붙은 숫자
월과 요일 필드는 세 글자 영문 이름——JAN부터 DEC까지, SUN부터 SAT까지——을 숫자의 별칭으로 받습니다. 0 9 * JAN MON과 0 9 * 1 1은 같은 스케줄이지만, 이름 버전은 다음 독자에게 스스로를 설명하고 오프바이원 수정에도 견딥니다.
- 대소문자 무관이름 파싱은 대소문자를 구분하지 않습니다. mon, Mon, MON 모두 되지만, 대문자가 의도적으로 읽히는 관례입니다.
- 범위 안의 이름이름은 범위와 목록 안에서도 쓸 수 있습니다. MON-FRI가 표준 평일 구간이고, JAN,APR,JUL,OCT는 분기 월을 고릅니다.
- 설명 읽기Cron 작성 및 설명 도구는 표현식을 정규화하고 각 필드를 따로 설명합니다. “month: every value”, “weekday: 1, 2, 3, 4, 5”처럼요. 파서가 이름을 의도대로 읽었는지 확인할 수 있습니다.
두 날짜 필드는 OR로 결합된다
이것이 cron의 가장 비싼 놀라움입니다. 일과 요일이 둘 다 제한되어 있을 때——어느 쪽도 별표가 아닐 때——스케줄은 둘 중 하나라도 일치하면 발화합니다. 0 9 13 * FRI는 “13일의 금요일”이 아니라 매월 13일 그리고 매주 금요일을 뜻합니다.
설명 도구의 출력은 이 점을 명시합니다. 의미론을 dom-dow-or로 표시해 계산된 실행과 함께 보여주므로, 의도보다 훨씬 자주 발화할 표현식은 crontab에 들어가기 전에 정체를 드러냅니다.
- 와일드카드 하나는 단순어느 한쪽 날짜 필드가 별표이면 다른 쪽이 단독으로 지배합니다. 대부분의 사람이 어디서나 성립한다고 생각하는 직관적 동작입니다.
- 둘 다 제한은 OR둘 다 제한이면 OR입니다. 고전적인 Vixie cron 의미론으로, 대부분의 Unix 스케줄러가 이를 따라 일 또는 요일이 일치하면 작업을 실행합니다.
- AND는 우회가 필요진짜 “13일의 금요일”을 맞히려면 cron이 13일을 고르게 하고 명령 자체가 요일을 확인하게 하세요. 아니면 AND 의미론을 가진 스케줄러를 써야 하는데, 고전 cron은 그것이 아닙니다.
일요일은 0, 보통은 7이기도 하다
요일 필드는 일요일을 0, 월요일을 1로 매기고 토요일 6까지 갑니다. 대부분의 구현은 월요일부터 세는 사람들을 위해 7도 두 번째 일요일로 받습니다. Toolars 파서는 내부적으로 7을 0으로 정규화합니다. 하지만 둘 중 하나만 받는 시스템도 있고, 월요일을 1로 시작하는 ISO식 번호 매기기도 다른 곳에 존재합니다.
- 0과 77이 받아들여지는 곳에서 0과 7은 둘 다 일요일입니다. 0으로 쓰는 것이 스케줄러 간 이식성 있는 선택입니다.
- 조용한 오프바이원7을 거부하는 시스템에서 요일 7은 배포 시점에 요란하게 실패하지만, “월요일부터 센 일곱 번째 날”로 잘못 읽힌 요일은 엉뚱한 요일에 조용히 실패합니다.
- 플랫폼별 재확인표현식이 구현 사이를 옮길 때——시스템 crontab, 컨테이너 플랫폼, CI 스케줄러——번호 매기기가 여정을 무사히 넘겼다고 가정하지 말고 요일 번호를 다시 확인하세요.
서머타임은 스케줄을 휘게 한다
Cron은 스케줄러의 시간대에 있는 벽시계 시각으로 발화하는데, 그 벽시계는 1년에 두 번 말썽을 부립니다. 봄철 앞당기기 공백에서는 02:30 같은 로컬 시각이 아예 존재하지 않고, 가을철 되돌리기에서는 그 시각이 두 번 존재합니다. 그 분에 고정된 스케줄은 3월에 실행을 하나 건너뛰고 11월에는 두 번 발화할 수 있습니다.
- 사라지는 한 시간봄 공백: 전환의 밤에 02:30 작업은 일치하는 벽시계 시각이 없어 아무것도 발화하지 않습니다. 오류도 재시도도 없이, 그저 실행 하나가 사라집니다.
- 두 배가 되는 한 시간가을 중복: 같은 벽시계 시각이 두 번 옵니다. 작업이 한 번 실행될지 두 번 실행될지는 구현에 따라 다릅니다. 검증하지 않았다면 두 번이라고 가정하세요.
- UTC에는 DST가 없다깔끔한 탈출구는 UTC입니다. 서머타임 전환이 없어서 30 2 * * *는 1년 내내 매일 같은 순간을 뜻합니다. 설명 도구는 UTC, 기기의 로컬 시간대, 그리고 America/New_York, Europe/London 같은 명명된 시간대를 제공합니다.
희망이 아니라 다음 실행으로 검증하기
올바른 표현식과 그럴듯해 보이는 표현식의 차이는 구체적인 발화 시각 목록입니다. Cron 작성 및 설명 도구는 선택한 시간대에서 지금부터 다음 10회 실행을 계산하며 최대 366일 앞까지 탐색하고, 백그라운드 워커에서 평가하므로 무거운 표현식도 탭을 멈추게 할 수 없습니다.
- 실행 읽기처음 몇 회 실행을 의도와 대조하세요. “평일 09:00”이면 월요일부터 금요일 9시가 나와야 하고, 목록에 토요일이 있으면 OR 함정이 자수하는 것입니다.
- 전환 한 번 건너기서머타임 경계를 일부러 건너세요. 명명된 시간대에서 3월이나 11월 날짜를 골라 시계가 움직일 때 스케줄이 여전히 기대대로인지 확인합니다.
- 명시적 오류실패는 명시적입니다. 잘못된 필드, 틀린 필드 개수, 탐색 창 안에서 10회 실행을 만들 수 없는 스케줄은 조용한 빈 목록이 아니라 각각 이름 있는 오류를 받습니다.
스케줄과 패턴은 같은 규율을 공유합니다.
둘 다 파괴 반경이 큰 작은 문자열입니다. 정규 표현식을 위한 작성-테스트-리팩터링 루프를, 타임아웃이 있는 로컬 워커에서 배워 보세요.