이번 문서의 목표: 이 파일을 다 읽으면 crontab의 시간 필드 5칸을 자를 대지 않고 손으로 해석할 수 있고, 요일 필드의 0과 7이 모두 일요일이라는 함정과 일·요일 필드의 OR 결합 규칙을 설명할 수 있으며, at으로 일회성 작업을 예약할 수 있다.
사람이 매번 실행하지 않아도 되게: 작업 예약이 필요한 이유
매일 새벽 로그 파일을 정리하거나, 매주 데이터베이스를 백업하는 작업을 상상해 보자. 이런 작업을 사람이 매번 새벽에 일어나 직접 명령을 입력한다면 비효율적이고 실수하기도 쉽다. 리눅스는 “정해진 시각에 정해진 명령을 대신 실행해 주는” 예약 기능을 시스템 차원에서 제공한다. 이 기능을 담당하는 것이 크론(cron)과 at이다.
쉽게 말하면: cron은 “매주 월요일마다”처럼 되풀이되는 알람이고, at은 “오늘 밤 11시에 딱 한 번”처럼 일회성 알람이다.
정의
- cron: 정해진 주기로 반복 실행되는 작업을 예약하는 데몬(daemon, 사용자와 직접 상호작용하지 않고 백그라운드에서 계속 대기하며 작업을 처리하는 프로세스. 13편 참고)이다. 실제 데몬 프로세스 이름은 배포판에 따라
crond또는cron이다. - crontab: cron이 실행할 작업 목록을 적어 두는 표(table) 형식의 파일, 그리고 그 파일을 편집·조회·삭제하는 명령의 이름이기도 하다.
- at: 지정한 시각에 단 한 번만 실행되는 작업을 예약하는 명령이다.
반복 작업과 일회성 작업을 가르는 기준
| 구분 | 예 | 사용하는 도구 |
|---|---|---|
| 반복 작업 | 매일 새벽 2시 로그 정리, 평일마다 백업 | cron(crontab) |
| 일회성 작업 | 오늘 밤 11시에 딱 한 번 알림 발송, 30분 뒤에 서비스 재시작 | at |
자주 틀리는 점: “한 번만 실행하고 싶은데 crontab에 등록했다가, 작업이 끝난 뒤 crontab에서 그 줄을 지우는 것을 깜빡해 다음 주에도 또 실행됐다”는 실수가 흔하다. 애초에 일회성 작업은 at으로 예약하는 것이 원칙이다. crontab의 시간 필드는 구조상 “특정 날짜 하루만, 그리고 다시는 반복하지 않음”을 표현할 수 없다.
crontab 시간 필드 5칸
crontab 파일의 각 줄은 다음과 같은 형식을 가진다.
분 시 일 월 요일 실행할_명령이 5개의 시간 필드를 순서와 범위까지 정확히 외우는 것이 이 단원의 핵심이다. 순서를 헷갈리면 전혀 다른 시각에 실행되는 함정 문제에 바로 걸린다.
| 순서 | 필드 | 영문 | 값의 범위 |
|---|---|---|---|
| 1 | 분 | minute | 0–59 |
| 2 | 시 | hour | 0–23 |
| 3 | 일 | day of month | 1–31 |
| 4 | 월 | month | 1–12 |
| 5 | 요일 | day of week | 0–7 (0과 7 모두 일요일, 1은 월요일) |
비유: 다섯 칸의 순서는 “분·시·일·월·요일”로, 시각을 작은 단위(분)에서 큰 단위(요일) 쪽으로 읽어 나가는 순서라고 기억하면 헷갈리지 않는다. “분시일월요”로 소리 내어 외워 두면 실전에서 순서가 헷갈리지 않는다.
요일 필드의 함정: 0과 7이 모두 일요일
요일 필드는 0부터 6까지만 있는 것이 아니라 7까지 허용된다. 그런데 0과 7이 둘 다 일요일을 가리킨다. 이것은 cron 규격이 두 관습(0을 시작으로 세는 방식과, 1주일을 월요일 시작으로 보고 일요일을 7번째 요일로 세는 방식)을 모두 지원하기 위해 남겨 둔 중복 표기다.
| 요일 필드 값 | 요일 |
|---|---|
0 또는 7 | 일요일 |
1 | 월요일 |
2 | 화요일 |
3 | 수요일 |
4 | 목요일 |
5 | 금요일 |
6 | 토요일 |
자주 틀리는 점: “요일 필드는 0부터 6까지다”라고만 외우면, 7이 들어간 표현식을 만났을 때 “잘못된 값” 또는 “존재하지 않는 요일”이라고 착각해 오답을 고르기 쉽다. 7도 유효한 값이며 일요일을 뜻한다는 점을 반드시 함께 기억해야 한다.
특수 기호: *, ,, -, /
각 필드 안에는 숫자를 하나만 쓰는 것이 아니라, 다음 네 가지 기호로 여러 값을 한 번에 표현할 수 있다.
| 기호 | 의미 | 예시 | 예시 해석 |
|---|---|---|---|
* | 해당 필드의 모든 값(전체) | 시 필드에 * | 0시부터 23시까지 매 시간 |
, | 나열(여러 특정 값) | 요일 필드에 1,3,5 | 월요일, 수요일, 금요일 |
- | 범위(연속된 구간) | 요일 필드에 1-5 | 월요일부터 금요일까지 |
/ | 간격(일정 단위로 건너뛰기) | 분 필드에 */10 | 0분, 10분, 20분, …, 50분마다(10분 간격) |
-와 /를 함께 쓸 수도 있다. 예를 들어 분 필드의 0-30/10은 “0분부터 30분까지의 범위 안에서 10분 간격”을 뜻해 0, 10, 20, 30분에 실행된다.
자주 틀리는 점: */10을 “10분마다 정확히 딱 10번씩만 실행”이라고 오해하는 경우가 있다. 실제로는 “그 필드의 전체 범위를 10 간격으로 나눈 값마다”라는 뜻이다. 분 필드라면 0부터 59까지를 10 간격으로 나눈 0, 10, 20, 30, 40, 50에 실행되므로 한 시간에 6번이다.
cron 표현식 해석 연습
지금까지 익힌 순서·범위·기호를 실제 예제에 적용해 본다. 왼쪽부터 분·시·일·월·요일 순서를 놓치지 않는 것이 핵심이다.
예제 1: 30 2 * * 1
| 필드 | 값 | 해석 |
|---|---|---|
| 분 | 30 | 30분 |
| 시 | 2 | 2시(오전 2시) |
| 일 | * | 모든 날짜 |
| 월 | * | 모든 달 |
| 요일 | 1 | 월요일 |
해석: 매주 월요일 오전 2시 30분에 실행된다. 일과 월이 *(전체, 즉 조건 없음)이므로 사실상 요일 조건 하나만 남아 “매주 월요일”이 된다.
예제 2: 0 9 1 * *
| 필드 | 값 | 해석 |
|---|---|---|
| 분 | 0 | 정각 |
| 시 | 9 | 9시(오전 9시) |
| 일 | 1 | 매월 1일 |
| 월 | * | 모든 달 |
| 요일 | * | 모든 요일(조건 없음) |
해석: 매월 1일 오전 9시 정각에 실행된다. “매월 첫날 아침에 실행하는 정기 보고서 작성” 같은 작업에 쓰인다.
예제 3: */15 * * * *
| 필드 | 값 | 해석 |
|---|---|---|
| 분 | */15 | 0, 15, 30, 45분(15분 간격) |
| 시 | * | 매 시간 |
| 일 | * | 매일 |
| 월 | * | 매달 |
| 요일 | * | 매 요일 |
해석: 하루 종일 15분마다 실행된다. 서버 상태를 주기적으로 점검하는 모니터링 스크립트에 흔히 쓰이는 형태다.
예제 4: 0 18 * * 5
| 필드 | 값 | 해석 |
|---|---|---|
| 분 | 0 | 정각 |
| 시 | 18 | 18시(오후 6시) |
| 일 | * | 모든 날짜 |
| 월 | * | 모든 달 |
| 요일 | 5 | 금요일 |
해석: 매주 금요일 오후 6시 정각에 실행된다. 주간 업무를 마감하며 보고서를 발송하는 작업에 어울린다.
예제 5: 0 3 1,15 * *
| 필드 | 값 | 해석 |
|---|---|---|
| 분 | 0 | 정각 |
| 시 | 3 | 3시(오전 3시) |
| 일 | 1,15 | 1일과 15일(나열) |
| 월 | * | 모든 달 |
| 요일 | * | 모든 요일(조건 없음) |
해석: 매달 1일과 15일, 오전 3시 정각에 실행된다. 요일 필드가 *이므로 요일 조건은 걸리지 않고, 오직 “일” 필드의 나열(1,15)만 조건으로 작동한다.
예제 6(응용): 일과 요일이 둘 다 지정된 경우 — OR로 결합된다
30 2 1 * 1| 필드 | 값 | 해석 |
|---|---|---|
| 분 | 30 | 30분 |
| 시 | 2 | 2시(오전 2시) |
| 일 | 1 | 매월 1일 |
| 월 | * | 모든 달 |
| 요일 | 1 | 월요일 |
해석: 언뜻 보면 “매월 1일이면서 동시에 월요일인 날”로 좁혀 읽기 쉽지만, 이것은 함정이다. cron은 일(day of month)과 요일(day of week) 필드가 모두 *가 아닌 구체적인 값으로 지정되면, 이 둘을 AND(그리고)가 아니라 OR(또는)로 결합한다. 따라서 이 표현식은 “매월 1일 오전 2시 30분” 또는 “매주 월요일 오전 2시 30분” 중 어느 하나라도 해당하면 실행된다는 뜻이다. 즉 1일이 월요일이 아니어도 실행되고, 1일이 아닌 월요일에도 실행된다.
자주 틀리는 점: reference 기출·모의고사 자료에서 이 OR 결합 규칙은 여러 차례 반복 출제된 대표적인 함정이다. “일과 요일을 동시에 만족하는 날에만 실행된다”는 선택지가 나오면 틀린 설명이다. 두 필드를 모두 특정 값으로 채우고 싶다면, cron 표현식 하나로는 “AND” 조건을 만들 수 없으므로 한쪽만 지정하고 나머지 조건은 스크립트 내부에서
date명령 등으로 직접 검사해야 한다.
반대로 만들어 보기: “매주 일요일 새벽 3시”를 표현식으로
말로 된 조건을 다시 5칸으로 쪼개 넣는 연습도 똑같이 중요하다.
- 분: “정각”이므로
0 - 시: “새벽 3시”이므로
3 - 일: 날짜 조건이 없으므로
* - 월: 달 조건이 없으므로
* - 요일: “일요일”이므로
0(또는7)
0 3 * * 0이렇게 완성한다. 만약 “매주 일요일과 수요일 새벽 3시”라면 요일 필드를 나열 기호로 묶어 0,3으로 쓰면 된다.
0 3 * * 0,3crontab 명령 사용법
작업을 실제로 등록·조회·삭제할 때는 crontab 명령을 쓴다. 파일을 직접 열어 편집하는 것이 아니라 명령을 통해 다루는 것이 원칙이다.
| 명령 | 동작 |
|---|---|
crontab -e | 현재 사용자의 crontab을 편집기로 연다(edit) |
crontab -l | 현재 사용자의 crontab 내용을 출력한다(list) |
crontab -r | 현재 사용자의 crontab 전체를 삭제한다(remove). 확인 절차 없이 즉시 지워지므로 주의한다 |
crontab -u 사용자명 -e | (root 권한 필요) 다른 사용자의 crontab을 편집한다 |
crontab -u 사용자명 -r | (root 권한 필요) 다른 사용자의 crontab 전체를 삭제한다 |
자주 틀리는 점: -r은 편집(-e)이나 목록(-l)과 헷갈리기 쉬운데, “remove(제거)“의 r로 기억하면 헤갈리지 않는다. 또한 -u는 반드시 대상 사용자명과 함께 써야 하며, crontab -u ihduser처럼 뒤에 -e나 -r 없이 단독으로 쓰면 편집기가 열릴 뿐 삭제나 조회가 되지 않는다.
관련 설정 파일로는 /etc/crontab(시스템 전역 작업을 등록하는 파일로, 사용자 필드가 추가로 있다), /var/spool/cron/사용자명(각 사용자가 crontab -e로 등록한 내용이 실제 저장되는 위치), /etc/cron.d/(패키지가 개별적으로 등록하는 작업 조각 파일들을 모아 두는 디렉터리)가 있다. 그리고 /etc/cron.allow와 /etc/cron.deny로 어떤 사용자가 cron을 쓸 수 있는지 제한할 수 있다. /etc/cron.allow가 존재하면 그 목록에 있는 사용자만 허용되고, 없으면 /etc/cron.deny에 없는 모든 사용자가 허용된다.
at — 일회성 작업 예약
at은 지정한 시각에 딱 한 번 실행되는 명령을 예약한다.
$ at 23:00
at> /home/ihduser/backup.sh
at> <Ctrl+D>
job 3 at Thu Sep 10 23:00:00 2026at 23:00을 입력하면 at> 프롬프트가 나타나고, 그 안에서 실행할 명령을 한 줄씩 입력한 뒤 Ctrl+D(EOF, 입력 종료 신호)로 마친다. “오늘 밤 11시” 같은 상대적인 표현도 쓸 수 있다.
$ at now + 30 minutes
$ at 5:00pm tomorrow
$ at 10:00 2026-12-25| 명령 | 동작 |
|---|---|
at 시각 | 지정 시각에 실행할 작업을 등록한다 |
atq | 예약된 at 작업 목록을 본다(queue) |
atrm 작업번호 | 예약된 특정 작업을 취소한다(remove) |
자주 틀리는 점: at으로 예약한 작업이 실행되려면 atd라는 별도의 데몬이 실행 중이어야 한다. cron과 atd는 서로 다른 데몬으로, cron이 실행 중이어도 atd가 꺼져 있으면 at으로 예약한 작업은 실행되지 않는다. 마찬가지로 at.allow, at.deny 파일이 cron.allow, cron.deny와 별개로 존재해 사용 권한을 관리한다.
실행 결과와 로그 확인
cron이나 at으로 실행한 작업은 화면에 결과가 보이지 않으므로, 무엇이 언제 실행됐는지 확인하려면 로그를 봐야 한다. 배포판에 따라 /var/log/cron(레드햇 계열) 또는 /var/log/syslog(데비안 계열, CRON 태그로 기록됨)에서 실행 이력을 확인할 수 있다. 작업 자체의 출력(표준출력·표준에러, 20편 참고)은 기본적으로 그 작업을 등록한 사용자에게 메일로 전송되며, 필요 없다면 crontab 명령 줄 끝에 > /dev/null 2>&1을 붙여 버린다.
*/30 * * * * /home/ihduser/check.sh > /dev/null 2>&1이 줄은 30분마다 check.sh를 실행하되, 그 출력과 에러를 모두 버려 메일이 쌓이지 않게 한다.
직접 해보기
00편에서 만든 Rocky Linux 컨테이너에서 진행합니다. 아직 안 만들었다면 00편을 먼저 보세요.
crontab -e는 편집기가 뜨는 방식이라 여기서는 대신 crontab -l(조회)과 파이프로 등록하는 방식을 쓴다. 앞에서 만든 “매주 일요일 새벽 3시” 표현식 0 3 * * 0을 실제로 등록해 본다.
crontab -l
echo "0 3 * * 0 /root/backup.sh" | crontab -
crontab -l
cat /etc/crontab무엇을 보아야 하나: 첫 번째 crontab -l은 보통 “no crontab for root” 같은 메시지를 낸다(아직 등록한 것이 없다는 뜻). 두 번째 crontab -l에서는 방금 넣은 0 3 * * 0 /root/backup.sh 줄이 분·시·일·월·요일 순서 그대로 보이는지 확인한다. /etc/crontab에는 시간 필드 뒤에 사용자 필드가 하나 더 있다는 차이도 함께 확인한다.
왜 이걸 해보나: 컨테이너에는 cron 데몬이 없을 수 있어 실제로 새벽 3시에 실행되는 것까지는 확인하기 어렵다(등록·조회까지만 확인해도 충분하다). 하지만 5칸을 손으로 채워 등록해 보면, 표현식을 거꾸로 만들라는 시험 문제에 대비하는 감각을 몸으로 익히게 된다.
핵심 정리
- 반복 작업은
cron(crontab), 일회성 작업은at을 쓴다. - crontab 시간 필드는 분(0–59) 시(0–23) 일(1–31) 월(1–12) 요일(0–7) 순서이며, 요일의
0과7은 모두 일요일이다. *는 전체,,는 나열,-는 범위,/는 간격을 뜻한다.- 일(day of month)과 요일(day of week)이 둘 다
*가 아닌 값으로 지정되면 AND가 아니라 OR로 결합된다. crontab -e(편집),-l(조회),-r(전체 삭제),-u 사용자(대상 지정)를 구분해서 쓴다.at은atq로 조회,atrm으로 취소한다.