Cron 표현식 파서

공백으로 구분한 다섯 개 필드, 또는 @daily 같은 단축 표기.

0 */2 * * 1-5, 30 3 * JAN,JUL 1 같은 줄이 가득한 crontab을 물려받았다고 해 봅시다. 이 파서는 각 필드를 그 필드가 실제로 일치하는 값으로 펼쳐 보여 줍니다. */2가 어디까지 포함하는지 짐작할 필요 없이, 그 표기가 시 필드에서 고르는 값 열두 개와 그 개수가 나란히 표시됩니다. 정규화된 5필드 형태, 표현식이 잘 알려진 함정에 해당할 때 뜨는 경고, 사용자 시간대로 계산한 다음 실행 시각 5개도 함께 보여 줍니다.

cron 표현식을 해석하는 방법

  1. 1

    표현식 붙여넣기

    공백으로 구분한 5필드 한 줄(`* * * * *`), 즉 분, 시, 일, 월, 요일입니다. `@daily` 같은 단축 표기도 그대로 인식합니다.

  2. 2

    펼쳐진 필드 읽기

    각 필드마다 일치하는 값과 그 개수가 함께 표시됩니다. 시 필드의 `*/2`라면 0, 2, 4를 비롯해 그 표기가 포함하는 나머지 아홉 개까지 모두 나옵니다.

  3. 3

    다음 실행 미리보기 확인

    앞으로 실행될 시각 5개를 사용자 시간대 기준으로 브라우저에서 직접 계산합니다. 의도와 다르면 표현식을 다듬으세요.

  4. 4

    경고 읽기

    파서는 흔한 함정을 짚어 줍니다. 두 날짜 필드를 모두 지정한 경우, 달력에 존재할 수 없는 날짜, 표준 cron이 이해하지 못하는 연산자가 그렇습니다.

각 필드가 펼쳐지는 값

필드는 값 하나가 아니라 값의 집합입니다. 그 집합이 얼마나 큰지 알면 여기까지 찾아온 궁금증이 대개 그 자리에서 풀립니다.

필드 범위 *가 일치하는 값 참고
분 0-59 60개 폭주하는 작업의 가장 흔한 원인
시 0-23 24개 1-12시가 아니라 언제나 24시간제
일 1-31 31개 짧은 달은 없는 날짜를 그냥 건너뜁니다
월 1-12 12개 JAN부터 DEC까지 이름으로도 쓸 수 있습니다
요일 0-7 7개 0과 7 모두 일요일

필드 안에서 쓰는 연산자는 다음과 같습니다. *는 모든 값, 1,5,10은 목록, 1-5는 범위, */15는 범위의 시작점부터 세는 스텝, 0-45/15는 범위 안에서 세는 스텝입니다.

이름과 단축 표기도 인식합니다

월 이름과 요일 이름도 그대로 해석해 일치하는 숫자로 펼칩니다. 그래서 30 3 * JAN,JUL 1은 월이 1, 7, 요일이 1로 표시됩니다. 단축 표기는 다른 처리에 앞서 5필드 형태로 먼저 펼쳐집니다.

단축 표기 펼쳐진 형태 의미
@yearly, @annually 0 0 1 1 * 1월 1일 자정
@monthly 0 0 1 * * 매월 1일 자정
@weekly 0 0 * * 0 매주 일요일 자정
@daily, @midnight 0 0 * * * 매일 자정
@hourly 0 * * * * 매시 정각

@reboot도 인식하지만 펼칠 일정이 없습니다. 시스템이 시작될 때 한 번 실행되므로 미리 보여 줄 실행 시각이 없습니다.

꼭 읽어야 할 경고

  • 일 필드와 요일 필드를 모두 지정한 경우. 0 0 1 * MON은 “1일이면서 월요일인 날”이라는 뜻이 아닙니다. 표준 cron은 일 필드와 요일 필드가 모두 지정되어 있으면 두 필드를 OR로 처리합니다. 따라서 이 줄은 매월 1일에도 실행되고 매주 월요일에도 실행됩니다. 파서는 이 경고를 띄우고, 다음 실행 미리보기도 OR 규칙을 그대로 따릅니다.
  • 절대 오지 않는 날짜. 0 0 30 2 *는 2월 30일을 요구합니다. 문법상으로는 올바르고 cron도 이 줄을 받아들이지만, 실제로는 한 번도 실행되지 않습니다. 파서는 아무 설명 없이 빈 목록만 보여 주는 대신 그 사실을 알려 줍니다.
  • Quartz 연산자. L(마지막), W(가장 가까운 평일), #(그 달의 N번째 요일), ?는 Quartz 확장이며 표준 crontab에는 없습니다. 5필드 한 줄 안에 들어 있으면 인식해서 표시해 주고, 해당 필드에는 값 목록 대신 Quartz 연산자라는 안내가 나옵니다. 표준 cron이라면 이 줄을 아예 실행하지 않으므로 실행 시각은 계산하지 않습니다.

아예 거부되는 입력

  • 필드 개수가 맞지 않는 경우. 초가 붙은 6필드 Quartz 줄이나 연도까지 붙은 7필드 줄은 필드 개수 단계에서 거부됩니다.
  • 범위를 벗어난 값. 예를 들어 분 75나 월 13이 그렇습니다.
  • 거꾸로 지정한 범위. 5-1 같은 경우입니다.
  • 0으로 지정한 스텝. */0이 그렇습니다.

거부될 때마다 원인이 된 필드와 값을 함께 알려 주므로, 줄 전체를 다시 쓰지 않고 한 군데만 고치면 됩니다.

시간대

다음 실행 미리보기는 사용자 브라우저에서, 기기에 설정된 시간대로 계산합니다. 반면 crontab은 그것이 올라가 있는 머신의 시간대로 동작합니다. 그러니 서버는 UTC로 돌아가는데 기기의 시간대는 다르다면, 두 시각을 견주기 전에 시차만큼 옮겨서 따져 보세요.

자주 묻는 질문

일정으로는 처리하지 않습니다. 초가 붙은 6필드 Quartz 줄이나 연도까지 붙은 7필드 줄은 필드 개수 단계에서 거부됩니다. 일반적인 5필드 줄 안에 들어 있는 Quartz 연산자(L, W, #, ?)는 경우가 다릅니다. 인식해서 표시해 주기는 하지만 실행 시각은 계산하지 않습니다. 표준 cron 역시 그 줄을 실행하지 않기 때문입니다.

원인은 대개 둘 중 하나입니다. 기기와 crontab을 실행하는 서버 사이의 시차, 아니면 두 날짜 필드를 모두 지정한 경우입니다. 일 필드와 요일 필드를 모두 지정하면 cron은 두 조건이 다 맞을 때가 아니라 둘 중 하나만 맞아도 작업을 실행합니다. 그래서 0 0 1 * MON은 대부분의 예상보다 훨씬 자주 실행됩니다. 각 필드 옆에 붙은 값의 개수를 보면 생각보다 넓은 필드를 가장 빨리 찾아낼 수 있습니다.

네. Kubernetes는 표준 5필드 문법을 사용합니다. 한 가지 감안할 것은 시계입니다. CronJob은 클러스터의 시간대로 동작하고(spec.timeZone을 따로 지정하지 않으면 UTC), 이 페이지의 미리보기는 사용자 기기의 시간대를 사용합니다.

Linux cron이 다섯 필드 대신 받아들이는, 이름으로 쓰는 단축 표기입니다. @daily(@midnight도 같음)는 0 0 * * *, @weekly는 0 0 * * 0, @monthly는 0 0 1 * *, @yearly(@annually도 같음)는 0 0 1 1 *, @hourly는 0 * * * *입니다. 이 가운데 무엇을 붙여넣든 파서가 펼쳐진 5필드 형태를 보여 줍니다. @reboot만 예외입니다. 시스템이 시작될 때 실행되므로 일정도 없고 실행 시각도 없습니다.

관련 도구

이 도구는 다른 언어로도 제공됩니다