# 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 日） |
| `@monthly` | `0 0 1 * *` — 每月一次（1 日） |
| `@weekly` | `0 0 * * 0` — 每周一次（周日） |
| `@daily` | `0 0 * * *` — 每天一次（午夜） |
| `@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:00 |
| `*/15 * * * *` | 每 15 分钟 |
| `0 0 1 * *` | 每月 1 日午夜 |
| `0 8,17 * * *` | 每天 8:00 和 17:00 |

## 环境变量

### 设置变量

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

### 环境变量说明

| Command | Description |
|---------|-------------|
| `SHELL` | 运行命令的 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:00 |
| `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 |
|---------|-------------|
| `使用绝对路径` | cron PATH 很少，始终使用完整路径 |
| `重定向输出` | 用 `> /dev/null 2>&1` 避免邮件泛滥 |
| `锁文件` | 用 `flock` 防止并发执行 |
| `先手动测试` | 调度前先手动运行命令 |
| `使用 MAILTO` | 设置 `MAILTO=""` 抑制所有邮件 |
| `检查时区` | cron 使用系统时间，用 `date` 确认 |

### 用 flock 防止并发

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