Trình xác thực biểu thức Cron
Xác thực biểu thức cron và xem phân tích chi tiết từng trường
Biểu thức cron
minute hour day(month) month day(week)
Phân tích trường
*/15(0–59)Khai triển thành: 0, 15, 30, 45
0-6(0–23)Khai triển thành: 0, 1, 2, 3, 4, 5, 6
1,15(1–31)Khai triển thành: 1, 15
*(1–12)Khai triển thành: all (1–12)
1-5(0–6)Khai triển thành: 1, 2, 3, 4, 5
Xác Thực Biểu Thức Cron Là Gì?
Xác thực biểu thức cron là quá trình kiểm tra xem một chuỗi cron có tuân theo đúng quy tắc cú pháp trước khi được đưa vào bộ lập lịch hay không. Biểu thức cron sử dụng năm trường cách nhau bằng dấu cách (phút, giờ, ngày trong tháng, tháng, ngày trong tuần) để định nghĩa một lịch chạy định kỳ. Nếu bất kỳ trường nào chứa giá trị ngoài phạm vi cho phép, toán tử không hợp lệ, hoặc lỗi cấu trúc như sai số lượng trường, biểu thức sẽ bị bộ lập lịch từ chối khi triển khai hoặc âm thầm không khớp với bất kỳ thời điểm kích hoạt nào.
Xác thực biểu thức cron trực tuyến giúp phát hiện lỗi sớm hơn so với việc triển khai lên production và chờ đợi một tác vụ bị bỏ lỡ. Các lỗi thường gặp bao gồm: ghi 25 vào trường giờ (phạm vi hợp lệ: 0-23), sử dụng bước bằng 0 (*/0, là giá trị không xác định), đảo ngược giới hạn phạm vi (5-1 thay vì 1-5), hoặc thêm các trường dư thừa thuộc định dạng phi tiêu chuẩn như Quartz. Một trình kiểm tra cú pháp sẽ phát hiện các vấn đề này ngay lập tức và chỉ ra chính xác trường nào bị sai.
Xác thực cron khác với phân tích cron. Một trình phân tích nhận một biểu thức hợp lệ và chuyển đổi nó thành lịch dễ đọc. Một trình xác thực trả lời câu hỏi đơn giản hơn: biểu thức này có đúng định dạng không? Hãy xác thực trước khi phân tích — không có lý do gì để đưa một biểu thức không hợp lệ vào bộ lập lịch. Trong các pipeline CI/CD, xác thực cron tự động ngăn các lịch bị hỏng được merge vào tệp cấu hình.
Tại Sao Dùng Trình Xác Thực Cron Này?
Biểu thức cron có quy tắc cú pháp nghiêm ngặt, và các bộ lập lịch thường đưa ra thông báo lỗi không nhất quán khi các quy tắc đó bị vi phạm. Một số bộ lập lịch từ chối biểu thức với lỗi khó hiểu; số khác chấp nhận nó âm thầm và không bao giờ kích hoạt. Trình xác thực này cung cấp cho bạn chẩn đoán rõ ràng từng trường trước khi bạn triển khai.
Các Trường Hợp Sử Dụng Trình Xác Thực Cron
Các Lỗi Cú Pháp Cron Thường Gặp
Bảng dưới đây liệt kê các lỗi biểu thức cron phổ biến nhất và nguyên nhân gây ra chúng. Đây là những lỗi xuất hiện lặp đi lặp lại trong các cấu hình production và pipeline CI/CD.
| Loại lỗi | Ví dụ | Vấn đề xảy ra |
|---|---|---|
| Too few fields | 0 9 * * | Missing the day-of-week field. Standard cron requires exactly 5 fields. |
| Too many fields | 0 0 9 * * 1 2026 | Extra fields. Some tools add seconds or year, but standard cron uses 5. |
| Value out of range | 0 25 * * * | Hour field accepts 0-23. Value 25 exceeds the maximum. |
| Invalid step base | 0 0 32/2 * * | Day-of-month starts at 32, which exceeds the 1-31 range. |
| Step of zero | */0 * * * * | Step value must be 1 or greater. Zero creates an infinite loop. |
| Empty field | 0 9 * * 1 | Double space creates an empty field. Each field needs a value. |
| Invalid character | 0 9 * * Mon-Fry | Typo in day name. Use three-letter abbreviations: MON, TUE, WED, THU, FRI, SAT, SUN. |
| Reversed range | 0 9 * * 5-1 | Range end (1) is less than start (5). Write 1-5 or use a list: 5,6,0,1. |
Biểu Thức Cron Hợp Lệ và Không Hợp Lệ
Tài liệu tham khảo nhanh về các biểu thức đúng định dạng bên cạnh các lỗi thường gặp. Dùng bảng này để kiểm tra biểu thức của bạn trước khi dán vào cấu hình bộ lập lịch.
Ví Dụ Code
Cách xác thực biểu thức cron theo chương trình trong JavaScript, Python, Go và Bash. Mỗi ví dụ cho thấy cách phát hiện cú pháp không hợp lệ và trích xuất thông báo lỗi có ý nghĩa.
import { parseExpression } from 'cron-parser';
// Validate a cron expression by attempting to parse it
function validateCron(expr) {
try {
parseExpression(expr);
return { valid: true, error: null };
} catch (err) {
return { valid: false, error: err.message };
}
}
console.log(validateCron('0 9 * * 1-5'));
// → { valid: true, error: null }
console.log(validateCron('0 25 * * *'));
// → { valid: false, error: "Constraint error, got value 25 expected range 0-23" }
// Validate with field-level detail using cron-validator
import { isValidCron } from 'cron-validator';
isValidCron('*/15 * * * *'); // → true
isValidCron('*/15 * * * *', { seconds: true }); // → false (expects 6 fields)
isValidCron('0 0 31 2 *'); // → true (syntactically valid, Feb 31 never fires)from croniter import croniter
# Validate by checking if croniter can parse the expression
def validate_cron(expr: str) -> dict:
if croniter.is_valid(expr):
return {"valid": True, "error": None}
# Get a more specific error message
try:
croniter(expr)
except (ValueError, KeyError) as e:
return {"valid": False, "error": str(e)}
return {"valid": False, "error": "Unknown error"}
print(validate_cron("0 9 * * 1-5"))
# → {'valid': True, 'error': None}
print(validate_cron("0 25 * * *"))
# → {'valid': False, 'error': '...out of range...'}
print(validate_cron("* * *"))
# → {'valid': False, 'error': 'Exactly 5 or 6 columns...'}
# Field-level validation
from crontab import CronTab
cron = CronTab(tab="")
job = cron.new(command="/bin/true")
try:
job.setall("0 9 * * 1-5")
print(job.is_valid()) # → True
except Exception as e:
print(f"Invalid: {e}")package main
import (
"fmt"
"github.com/robfig/cron/v3"
)
// ValidateCron checks whether a 5-field cron expression is syntactically correct
func ValidateCron(expr string) (bool, error) {
parser := cron.NewParser(
cron.Minute | cron.Hour | cron.Dom | cron.Month | cron.Dow,
)
_, err := parser.Parse(expr)
if err != nil {
return false, err
}
return true, nil
}
func main() {
exprs := []string{
"0 9 * * 1-5", // valid
"0 25 * * *", // invalid: hour 25
"*/15 * * * *", // valid
"0 0 32 * *", // invalid: day 32
}
for _, e := range exprs {
ok, err := ValidateCron(e)
if ok {
fmt.Printf("%-20s VALID
", e)
} else {
fmt.Printf("%-20s INVALID: %v
", e, err)
}
}
}#!/bin/bash
# Validate cron syntax using Python one-liner
validate_cron() {
python3 -c "
from croniter import croniter
import sys
expr = sys.argv[1]
if croniter.is_valid(expr):
print(f'VALID: {expr}')
sys.exit(0)
else:
print(f'INVALID: {expr}')
sys.exit(1)
" "$1"
}
validate_cron "0 9 * * 1-5" # → VALID: 0 9 * * 1-5
validate_cron "0 25 * * *" # → INVALID: 0 25 * * *
# Quick regex pre-check (catches field count and obvious issues)
cron_regex='^([0-9*/,-]+\s+){4}[0-9*/,-]+$'
echo "*/5 * * * *" | grep -Eq "$cron_regex" && echo "passes basic check"
echo "* * *" | grep -Eq "$cron_regex" || echo "fails basic check"