Trình tạo biểu thức Cron
Xây dựng và hiểu các lịch trình tác vụ cron một cách trực quan.
Cài đặt sẵn nhanh
5 lần thực thi tiếp theo
Tham khảo cú pháp cron
* · bất kỳ giá trị nào
*/5 · cứ 5 đơn vị
1,15 · ở các giá trị 1 và 15
1-5 · phạm vi từ 1 đến 5
Trường: phút (0-59), giờ (0-23), ngày trong tháng (1-31), tháng (1-12), thứ trong tuần (0-6, 0=Chủ nhật)
Lịch sử ngắn của biểu thức cron
Biểu thức cron năm trường có từ tháng 5 năm 1975, khi một phiên bản đầu được phát hành từ AT&T Bell Laboratories như một phần của Research Unix Phiên bản 7. Tên ám chỉ Chronos, hiện thân Hy Lạp của thời gian. Định dạng đơn giản: năm trường được phân tách bằng khoảng trắng (phút, giờ, ngày-trong-tháng, tháng, ngày-trong-tuần) trên một dòng trong /usr/lib/crontab. Việc viết lại Vixie cron bởi Paul Vixie năm 1987 đã trở thành triển khai hiện đại trên thực tế; mọi bản phân phối Linux lớn đều xuất xưởng một cron có nguồn gốc Vixie, và Vixie đã thêm crontab theo người dùng, hỗ trợ biến môi trường (MAILTO=, CRON_TZ=), và các macro phím tắt @hourly / @daily / @reboot mà mọi người sử dụng ngày nay. Cú pháp biểu thức cron sau đó rẽ nhánh thành hai đường. Quartz Scheduler (Java, James House, 1998; quyên góp cho Apache và Terracotta) đã thêm trường giây đứng đầu, trường năm tùy chọn đứng cuối, và các toán tử L (cuối cùng) / W (ngày làm việc) / # (lần xuất hiện thứ n), tạo ra cron sáu trường mà AWS EventBridge (ban đầu là CloudWatch Events, 2014) và chú thích @Scheduled của Spring sau đó đã áp dụng. Định dạng NCronTab được sử dụng bởi Azure Functions (2016) đặt giây đầu tiên nhưng giữ năm trường hành vi. Kỷ nguyên đám mây sau đó đã chuẩn hóa định dạng Vixie năm trường làm ngôn ngữ chung: Kubernetes CronJobs (alpha 1.4 năm 2016, GA trong 1.21 năm 2021) chấp nhận chính xác năm trường, cũng như GitHub Actions (on.schedule.cron, 2019), GCP Cloud Scheduler (2018), và Vercel Cron Jobs (2022). Các trình xây dựng cron trực quan, danh mục mà công cụ này thuộc về, xuất hiện vào khoảng 2010-2015: crontab.guru (Christine Dodrill, 2014) trở thành tài liệu tham khảo được trích dẫn nhiều nhất, và thư viện cron-descriptor (Brady Holt, ban đầu là .NET, được chuyển sang Java/Python/JS) đã hỗ trợ hầu hết các lớp dịch «cron bằng tiếng Anh đơn giản» mà các bộ giải mã và trình tạo dựa vào. Nửa thế kỷ sau Bell Labs, cùng năm trường này vẫn đang lên lịch các bản sao lưu hàng đêm của thế giới.
Giải phẫu của một biểu thức cron
- Năm trường, được phân tách bằng khoảng trắng. Theo thứ tự:
phút (0-59) giờ (0-23) ngày-trong-tháng (1-31) tháng (1-12) ngày-trong-tuần (0-6). Biểu thức0 9 * * 1có nghĩa là «phút 0, giờ 9, bất kỳ ngày-trong-tháng nào, bất kỳ tháng nào, ngày trong tuần 1 (Thứ Hai)», tức là 9:00 sáng mỗi Thứ Hai. Tháng được lập chỉ mục 1;0 0 1 0 *không hợp lệ vì không có tháng 0. - Bốn toán tử.
*khớp với mọi giá trị trong phạm vi của trường.,liệt kê các giá trị rời rạc:0,15,30,45trong trường phút.-định nghĩa một phạm vi:9-17trong trường giờ bao phủ 9 giờ sáng đến 5 giờ chiều./đặt bước:*/15trong phút kích hoạt ở 0, 15, 30, 45. Bốn toán tử này kết hợp tự do:*/15 8-18 * * 1-5có nghĩa là «cứ 15 phút giữa 8 và 18, chỉ ngày trong tuần». - Macro phím tắt. Vixie cron và hầu hết các trình phân tích cú pháp hiện đại chấp nhận
@yearly(hoặc@annually, tương đương với0 0 1 1 *),@monthly(0 0 1 * *),@weekly(0 0 * * 0),@daily(hoặc@midnight,0 0 * * *),@hourly(0 * * * *), và đặc biệt@reboot(chạy một lần khi cron daemon khởi động). Các nền tảng đám mây thay đổi: GitHub Actions và Vercel từ chối các macro. - Cái bẫy của bước.
*/Ntrong một trường có phạm vi a-b kích hoạt ở a, a+N, a+2N, ..., không nhất thiết mỗi N đơn vị của thời gian đồng hồ treo tường.*/7trong trường phút kích hoạt ở 0, 7, 14, 21, 28, 35, 42, 49, 56, sau đó nhảy về 0 ở đầu giờ tiếp theo, tạo ra khoảng trống 4 phút. Lịch trình cứ-7-phút thực sự không thể trong cron tiêu chuẩn mà không có wrapper. - Cái bẫy OR (ngày-trong-tháng so với ngày-trong-tuần). Khi cả hai trường bị hạn chế, cron Unix tiêu chuẩn kích hoạt khi một trong hai khớp, không phải cả hai.
0 0 1 * 1không có nghĩa là «Thứ Hai rơi vào ngày 1», nó có nghĩa là «mỗi ngày 1 của tháng, cộng với mỗi Thứ Hai». Trang mancrontab(5)rất rõ ràng. Quartz, AWS EventBridge, và timer systemd đều thể hiện «Thứ Hai đầu tiên» một cách sạch sẽ; Vixie cron cần một wrapper. - Đánh số ngày-trong-tuần thay đổi. Linux/Vixie, GitHub Actions, GCP Cloud Scheduler, Kubernetes, Azure NCronTab, và Spring 5.3+ đều sử dụng Chủ Nhật = 0 (Vixie cũng chấp nhận 7). Quartz và AWS EventBridge sử dụng Chủ Nhật = 1.
0 0 * * 1do đó có nghĩa là «mỗi Thứ Hai» trên Linux nhưng «mỗi Chủ Nhật» dưới Quartz. Sử dụng tên ba chữ cái (MON,TUE) khi tính di động quan trọng.
Nơi biểu thức được sử dụng
- cron Linux / macOS. Dán vào
crontab -etheo sau là lệnh. Tên (MON,JAN) và macro phím tắt (@hourly,@daily,@reboot) được chấp nhận. ĐặtCRON_TZ=America/New_Yorkở đầu crontab nếu máy chủ ở UTC nhưng bạn muốn lên lịch theo thời gian địa phương. - Kubernetes CronJob. Đặt
spec.schedulethành biểu thức năm trường của bạn.spec.timeZone(GA trong 1.27, tháng 3 năm 2023) nhận một múi giờ IANA như «Europe/Paris». NhúngTZ=trong chuỗi lịch trình bị từ chối từ 1.29 trở đi. Sử dụngspec.startingDeadlineSecondsđể kiểm soát hành vi bù lại sau sự cố. - GitHub Actions. Đưa vào
on.schedule.cron. Lịch trình chạy ở UTC, nhịp ngắn nhất là 5 phút (bất cứ thứ gì tinh hơn được làm tròn lặng lẽ), và các workflow đã lên lịch trong kho công khai tự động vô hiệu hóa sau 60 ngày không hoạt động của kho. Các chuỗi cron bên trong YAML phải được trích dẫn để tránh nhầm lẫn của trình phân tích cú pháp với dấu*đầu. - AWS EventBridge / EventBridge Scheduler. Sử dụng sáu trường:
cron(min hr dom mon dow yr). Yêu cầu?trong một trong các ngày-trong-tháng hoặc ngày-trong-tuần (không phải cả hai theo nghĩa đen). Các toán tử kiểu QuartzL(cuối cùng),W(ngày làm việc), và#(lần xuất hiện thứ n) đều hoạt động ở đây. Sản phẩm Scheduler (2022) đã thêm biểu thứcat()riêng cho timer một lần. - GCP Cloud Scheduler. Cú pháp năm trường khớp với Linux. Thuộc tính
timeZonenhận múi giờ IANA. Kết hợp với Cloud Pub/Sub hoặc các đích HTTP.retryConfigxử lý các lỗi thoáng qua; mặc định là không thử lại, điều này làm ngạc nhiên các kỹ sư mong đợi ngữ nghĩa ít nhất một lần. - Vercel Cron Jobs. Cú pháp năm trường trong
vercel.json. Cả hai trường ngày không thể được đặt cùng lúc. Các gói Hobby giới hạn nhịp ở hàng ngày; các gói Pro cho phép hàng giờ. Kích hoạt HTTP GET đến đường dẫn hàm của bạn, có nghĩa là hàm phải là idempotent nếu trình kích hoạt từng thử lại.
Tiêu chuẩn, phương ngữ và cột mốc
- cron AT&T Bell Labs (tháng 5 năm 1975). Bản gốc. Năm trường, không có crontab theo người dùng, chạy từ
/usr/lib/crontab. Một phần của Research Unix Phiên bản 7. Ngữ pháp được phân tách bằng khoảng trắng mà tất cả các biến thể hiện đại mở rộng. - Vixie cron (Paul Vixie, 1987). Viết lại mà mọi người đang chạy. Đã thêm crontabs theo người dùng, các macro
@hourly/@daily/@reboot, bí danh tên (MON,JAN), và các biến môi trườngMAILTO/CRON_TZ. Hầu hết các bản phân phối Linux xuất xưởng Vixie cron, dcron, hoặc cronie (một nhánh Red Hat của Vixie). - Quartz Scheduler (James House, 1998). Thư viện Java đã giới thiệu cron sáu trường (với giây ở đầu) và các toán tử
L/W/#. Quyên góp cho Apache và sau đó Terracotta. Chú thích@Scheduledcủa Spring nhúng ngữ nghĩa Quartz; Spring 5.3+ đã gây tranh cãi khi chuyển ngày-trong-tuần từ «Chủ Nhật=1» của Quartz sang «Chủ Nhật=0» của Linux, vì vậy cùng một chuỗi giờ có nghĩa là các ngày khác nhau dưới các phiên bản khác nhau. - timer systemd (Lennart Poettering, 2010). Thay thế cron trên hầu hết các bản phân phối Linux hiện đại. Sử dụng ngữ pháp khác (
OnCalendar=Mon..Fri 09:00), hỗ trợ cả lịch trình lịch và đơn điệu, ghi nhật ký vàojournald, có thể khai báo phụ thuộc dịch vụ, xác thực vớisystemd-analyze calendar, và kết hợp độ chính xác kiểu cron với khả năng bắt kịp kiểu anacron thông quaPersistent=true. - NCronTab (Azure Functions, 2016). Sáu trường với giây đầu tiên:
{second} {minute} {hour} {day} {month} {day-of-week}. Không có trường năm. Múi giờ mặc định là UTC; ghi đè bằng cài đặt ứng dụngWEBSITE_TIME_ZONEtrên các gói Linux App Service. - Cú pháp cron AWS EventBridge. Sáu trường với năm cuối cùng:
cron(min hr dom mon dow yr). Yêu cầu theo nghĩa đen?làm placeholder trong cái nào của dom/dow không được sử dụng. Hỗ trợ QuartzL,W,#. Ban đầu là CloudWatch Events (2014), được đổi tên thành EventBridge năm 2019. - Vấn đề di động 5-vs-6-trường. Dán biểu thức năm trường Linux vào Quartz hoặc Spring tạo ra lỗi «cron expression must consist of 6 fields»; dán biểu thức sáu trường vào cron Linux tạo ra «bad day-of-week» vì Linux đọc cột giây như phút. Lỗi ngược lại nguy hiểm hơn vì nó có thể phân tích cú pháp một cách lặng lẽ và chạy trên lịch trình sai.
- Mở rộng
H(hash) của Jenkins. Jenkins mở rộng cron tiêu chuẩn vớiH, chọn một giá trị ổn định nhưng ngẫu nhiên hóa cho mỗi công việc thay vì chạy mọi công việc cùng lúc.H * * * *có nghĩa là «mỗi giờ, nhưng ở phút khác nhau cho mỗi công việc», ngăn ngừa vấn đề «đàn sấm sét» khi nhiều công việc được lên lịch vào phút 0.
Các câu hỏi thường gặp khác
Năm trường có giống như sáu hoặc bảy không?
Không. Hình thức POSIX cổ điển là năm trường (phút, giờ, ngày-trong-tháng, tháng, ngày-trong-tuần). Quartz và Spring sử dụng sáu trường bằng cách thêm cột giây đầu, và Quartz chấp nhận trường năm tùy chọn thứ bảy. AWS EventBridge luôn sử dụng sáu trường kết thúc bằng năm (cron(min hr dom mon dow yr)). Dán biểu thức năm trường vào Quartz hoặc Spring tạo ra lỗi cú pháp; dán biểu thức sáu trường vào Linux thầm lặng hiểu sai các trường.
Khoảng thời gian nhỏ nhất mà cron có thể thể hiện là gì?
Mỗi phút (* * * * *) trên cron Unix tiêu chuẩn. Không có trường giây tích hợp. Các trình lên lịch như Quartz hoặc NCronTab thêm một cái nếu bạn cần nhịp dưới một phút, và timer systemd có thể sử dụng OnUnitActiveSec=30s. GitHub Actions giới hạn nhịp ngắn nhất ở 5 phút, và EventBridge kích hoạt trong cửa sổ 60 giây của thời gian đã lên lịch, vì vậy đừng dựa vào cron cho độ chính xác thời gian thực cứng.
Làm thế nào để tôi chạy một công việc vào ngày cuối cùng của tháng?
Cron năm trường tiêu chuẩn không có toán tử native «ngày cuối cùng của tháng». Quartz và AWS EventBridge hỗ trợ L trong trường ngày-trong-tháng: 0 0 L * ? kích hoạt vào nửa đêm vào ngày cuối cùng. Trên cron Linux thuần túy, cách giải quyết thông thường là lên lịch hàng ngày vào các ngày ứng viên và kiểm soát lệnh: 0 0 28-31 * * [ "$(date +\%d -d tomorrow)" = "01" ] && /path/to/script. Timer systemd thể hiện nó trực tiếp với OnCalendar=*-*-* 00:00:00.
Tại sao công việc cron của tôi không chạy khi tôi mong đợi?
Các nghi phạm thông thường, theo thứ tự: (1) máy chủ ở múi giờ khác với những gì bạn giả định (kiểm tra với date); (2) PATH không phải là những gì shell tương tác của bạn có, vì vậy một lệnh hoạt động ở dấu nhắc nhưng thất bại dưới cron (sử dụng đường dẫn tuyệt đối); (3) đầu ra đến email và bạn đã bỏ lỡ nó (đặt MAILTO="" hoặc chuyển hướng đến tệp nhật ký); (4) cron daemon không chạy (systemctl status cron); (5) cái bẫy OR (xem ở trên) đang kích hoạt vào những ngày bổ sung mà bạn không có ý định.
Sự khác biệt giữa cron, anacron và timer systemd là gì?
Cron mong đợi hệ thống đang chạy vào thời gian đã lên lịch và bỏ qua một cách lặng lẽ các công việc rơi vào trong thời gian ngừng hoạt động: tốt cho các máy chủ luôn bật, không tốt cho laptop. Anacron theo dõi dấu thời gian chạy lần cuối theo công việc và bắt kịp các công việc bị bỏ lỡ sau khi khởi động lại, với chi phí độ chính xác cấp ngày thay vì phút. Timer systemd thay thế cron trên hầu hết các bản phân phối Linux hiện đại: chúng hỗ trợ cả lịch trình lịch và đơn điệu, ghi nhật ký vào journald, có thể khai báo phụ thuộc dịch vụ, và sử dụng Persistent=true để kết hợp độ chính xác kiểu cron với khả năng bắt kịp kiểu anacron.
Múi giờ và giờ tiết kiệm ánh sáng ban ngày ảnh hưởng đến cron như thế nào?
Hầu hết các cron daemon diễn giải lịch trình trong múi giờ hệ thống. Trên các máy chủ đám mây, điều đó thường có nghĩa là UTC, vì vậy 0 9 * * * kích hoạt vào lúc 9 giờ sáng UTC, không phải 9 giờ sáng địa phương. Đặt CRON_TZ=America/New_York trong crontab Linux; Kubernetes sử dụng spec.timeZone; AWS, GCP, và Vercel mỗi cái nhận một múi giờ IANA rõ ràng. Trong quá trình mùa xuân tiến lên, các công việc được lên lịch vào giờ bị bỏ qua được chạy ngay sau đó bởi Vixie cron nhưng bị bỏ qua hoàn toàn bởi AWS EventBridge. Mẫu an toàn nhất là để cron ở UTC và chuyển đổi bên trong công việc.