# Cron 빠른 참조

*작업 스케줄링, crontab 문법, 특수 문자열, 로깅*

> Source: crontab(5) Manual Page · MIT

## 문법

### Crontab 형식

```
# ┌───── minute (0-59)
# │ ┌───── hour (0-23)
# │ │ ┌───── day of month (1-31)
# │ │ │ ┌───── month (1-12)
# │ │ │ │ ┌───── day of week (0-7, 0&7=Sun)
# * * * * * command
```

### 필드 값

| Command | Description |
|---------|-------------|
| `*` | 임의 값 (와일드카드) |
| `,` | 값 목록: `1,3,5` |
| `-` | 범위: `1-5` |
| `/` | 간격: `*/10` (10마다) |
| `0-59` | 분 범위 |
| `0-23` | 시 범위 |
| `1-31` | 일 범위 |
| `1-12` | 월 범위 (또는 JAN-DEC) |
| `0-7` | 요일 (0&7=일, 또는 SUN-SAT) |

## 특수 문자열

### 단축 스케줄

| Command | Description |
|---------|-------------|
| `@reboot` | 시작 시 한 번 실행 |
| `@yearly` | `0 0 1 1 *` — 연 1회 (1월 1일) |
| `@monthly` | `0 0 1 * *` — 월 1회 (1일) |
| `@weekly` | `0 0 * * 0` — 주 1회 (일요일) |
| `@daily` | `0 0 * * *` — 일 1회 (자정) |
| `@hourly` | `0 * * * *` — 시간마다 |

## 예시

### 일반 스케줄

```
30 2 * * *   /usr/local/bin/backup.sh
0 9 * * 1-5  /opt/report.sh
*/15 * * * *  /usr/bin/health-check.sh
0 0 1 * *    /opt/monthly-cleanup.sh
0 8,17 * * * /opt/notify.sh
```

### 스케줄 설명

| Command | Description |
|---------|-------------|
| `30 2 * * *` | 매일 오전 2시 30분 |
| `0 9 * * 1-5` | 평일 오전 9시 |
| `*/15 * * * *` | 15분마다 |
| `0 0 1 * *` | 매월 1일 자정 |
| `0 8,17 * * *` | 매일 오전 8시, 오후 5시 |

## 환경

### 변수 설정

```
SHELL=/bin/bash
PATH=/usr/local/bin:/usr/bin:/bin
MAILTO=admin@example.com
HOME=/home/deploy
* * * * * /opt/myjob.sh
```

### 환경 참고사항

| Command | Description |
|---------|-------------|
| `SHELL` | 명령 실행에 사용할 셸 (기본값 `/bin/sh`) |
| `PATH` | 검색 경로 (cron 기본값은 최소) |
| `MAILTO` | 출력을 이 주소로 이메일 발송 (빈 값 = 메일 없음) |
| `HOME` | cron 작업의 홈 디렉토리 |

## 로깅

### 출력 & 로깅

```
# redirect stdout + stderr to a log file
*/5 * * * * /opt/job.sh >> /var/log/job.log 2>&1
# discard all output
0 3 * * * /opt/job.sh > /dev/null 2>&1
# log only errors
0 3 * * * /opt/job.sh > /dev/null 2>> /var/log/job-err.log
```

### Cron 로그 보기

```
# Debian / Ubuntu (syslog)
grep CRON /var/log/syslog
# RHEL / CentOS
cat /var/log/cron
# journalctl (systemd)
journalctl -u cron --since "1 hour ago"
```

## 일반 스케줄

### 자주 쓰는 패턴

| Command | Description |
|---------|-------------|
| `0 * * * *` | 매 정시 |
| `*/5 * * * *` | 5분마다 |
| `*/30 * * * *` | 30분마다 |
| `0 0 * * *` | 매일 자정 |
| `0 6 * * 1` | 매주 월요일 오전 6시 |
| `0 0 1,15 * *` | 매월 1일, 15일 |
| `0 0 * * 5` | 매주 금요일 자정 |
| `0 0 1 1 *` | 매년 1월 1일 |

## crontab 명령어

### Crontab 관리

```
crontab -e               # edit your crontab
crontab -l               # list your crontab
crontab -r               # remove your crontab
crontab -u alice -l      # list another user's (root)
crontab /path/to/file    # install crontab from file
```

### 시스템 Crontab 위치

| Command | Description |
|---------|-------------|
| `/etc/crontab` | 시스템 전체 crontab (사용자 필드 있음) |
| `/etc/cron.d/` | 드롭인 cron 파일 |
| `/etc/cron.daily/` | 매일 실행되는 스크립트 |
| `/etc/cron.hourly/` | 매시간 실행되는 스크립트 |
| `/etc/cron.weekly/` | 매주 실행되는 스크립트 |
| `/etc/cron.monthly/` | 매월 실행되는 스크립트 |
| `/var/spool/cron/` | 사용자별 crontab 저장소 |

## 팁

### 모범 사례

| Command | Description |
|---------|-------------|
| `Use absolute paths` | cron PATH는 최소임; 항상 절대 경로 사용 |
| `Redirect output` | `> /dev/null 2>&1`로 메일 홍수 방지 |
| `Lock files` | `flock`으로 중복 실행 방지 |
| `Test first` | 스케줄 등록 전 명령을 수동으로 실행 테스트 |
| `Use MAILTO` | `MAILTO=""`로 모든 이메일 억제 |
| `Check timezone` | cron은 시스템 시간 사용; `date`로 확인 |

### flock으로 중복 실행 방지

```
# only run if not already running
* * * * * /usr/bin/flock -n /tmp/job.lock /opt/job.sh
```
