Cron job ba ngày một lần


93

Có thể chạy cronjob ba ngày một lần không? Hoặc có thể 10 lần / tháng.


4
Có nó là có thể và điều này thuộc về SuperUser.

chạy 3 ngày một lần bất kể ranh giới tháng có thể được thực hiện với anacron.
ryanpattison

Câu trả lời:


125

Chạy nó ba ngày một lần ...

0 0 */3 * *

Làm thế nào về điều đó?

Nếu bạn muốn nó chạy vào những ngày cụ thể trong tháng, như ngày 1, 4, 7, v.v. thì bạn chỉ cần có một điều kiện trong tập lệnh của mình để kiểm tra ngày hiện tại trong tháng.

if (((date('j') - 1) % 3))
   exit();

hoặc, như @mario đã chỉ ra, bạn có thể sử dụng date ('k') để lấy ngày trong năm thay vì dựa trên ngày trong tháng.


9
@whatshakin: Nó sẽ phụ thuộc vào mức độ chính xác mà bạn muốn "ba ngày một lần". Điều này sẽ hoạt động vào bất kỳ ngày nào chia hết cho 3. Về ranh giới tháng, nó sẽ không chính xác.
David

3
@whatshakin: Cú pháp cronjob thậm chí còn được mô tả trên Wikipedia: en.wikipedia.org/wiki/Cronjob
Felix Kling

4
Đây là một kết quả rất cao trên google, và như vậy sẽ tốt hơn nếu câu trả lời được chấp nhận là chính xác, điều này thì không. Tôi tin rằng lời giải thích của Tareco là đúng.
lynks

14
Câu trả lời là không đúng vì không có gợi ý nào thực sự chạy công việc 3 ngày một lần. 0 0 */3 * *nghĩa là chạy vào mùng 1, mùng 4, mùng 7,… ( */31-31/3nghĩa là 1,4,7...31) nên khoảng cách sẽ nhỏ hơn vào cuối tháng. (Nó sẽ chạy 2 ngày liên tiếp nếu tháng trước đó có 31 ngày.) Có date('j') % 3một vấn đề tương tự là mẫu khởi động lại hàng năm và các năm không có số ngày chia hết cho 3.
cjm

8
Tôi quá cân nhắc thật không may rằng đây đã được chấp nhận như một câu trả lời. Tôi thực sự đã tìm kiếm N ngày một lần, bất kể ranh giới tháng (những thứ như thực vật không quan tâm ngày nào trong tháng chúng lấy nước). Ít nhất tôi nghĩ rằng tôi đã xác định sau khi đọc tất cả các bình luận, rằng bộ đếm thời gian cron tự nó không hoàn toàn mô hình hóa mong muốn đó.
Travis Griggs,

69
* * */3 * *  that says, every minute of every hour on every three days. 

0 0 */3 * *  says at 00:00 (midnight) every three days.

đánh giá cao lời giải thích
pythonian29033 Ngày

2
Điều này thường sẽ cháy mỗi ba ngày, nhưng có thể bắn vào ngày hôm sau vào lúc bắt đầu của một tháng
Dziamid

24

Tôi không phải là một chuyên gia cron, nhưng làm thế nào về:

0 */72 * * *

Nó sẽ chạy mỗi 72 giờ không bị gián đoạn.

https://crontab.guru/#0_ / 72_ _ _


3
Điều này chính xác hơn giải pháp được chấp nhận. Câu trả lời được chấp nhận sẽ không thành công khi thay đổi tháng:then at 2019-02-28 00:00:00 then at 2019-03-01 00:00:00
Akira Yamamoto

Làm thế nào để một người tính toán khi điều này sẽ xảy ra?
Bruce Edge

2
Theo crontab.guru, điều này chạy mỗi ngày. Ai đúng?
velop

1
Giá trị trong cột giờ phải nằm trong khoảng từ 0 đến 23 theo crontab.guruman crontab .
harperville

1
* / 72 có hiệu quả giống như 0. Điều này chạy cứ sau nửa đêm.
battey

19

Bởi vì cron là "không trạng thái", nó không thể biểu thị chính xác "tần số", chỉ có những "mẫu" mà nó (dường như) liên tục khớp với thời gian hiện tại.

Diễn đạt lại câu hỏi của bạn làm cho điều này rõ ràng hơn: "có thể chạy cronjob lúc 00:01 sáng mỗi đêm trừ những đêm bỏ qua khi nó đã chạy trong vòng 2 đêm không?" Khi cron đang so sánh thời gian hiện tại với các mẫu thời gian yêu cầu công việc, không có cách nào cron có thể biết liệu nó có chạy công việc của bạn trong quá khứ hay không.

Thông thường, bạn phải chấm dứt sự kiện lặp lại đó và khởi động lại một sự kiện hoàn toàn mới; điều này minh họa mức độ diễn đạt hạn chế về cách các ứng dụng lịch thậm chí phức tạp thể hiện các mẫu lặp lại. Và tất nhiên Lịch có rất nhiều trạng thái - mỗi sự kiện riêng lẻ có thể bị xóa hoặc lên lịch lại một cách độc lập [trong hầu hết các ứng dụng lịch]).

Hơn nữa, bạn có thể muốn thực hiện công việc của mình vào mỗi đêm thứ 3 nếu thành công , nhưng nếu lần cuối cùng không thành công, hãy thử lại ngay lập tức, có thể là vào đêm tiếp theo (không phải đợi 3 ngày nữa) hoặc thậm chí sớm hơn, chẳng hạn như một giờ sau (nhưng dừng thử lại khi đến vào buổi sáng). Rõ ràng, cron không thể biết liệu công việc của bạn có thành công hay không và mẫu cũng không thể thể hiện lịch trình "thử lại" thường xuyên hơn.

MỌI LÚC - Bạn có thể tự mình làm những gì bạn muốn. Viết một kịch bản, yêu cầu cron chạy nó hàng đêm lúc 00:01 sáng. Tập lệnh này có thể kiểm tra dấu thời gian của thứ gì đó * ghi lại "lần chạy cuối cùng" và nếu cách đây> 3 ngày **, hãy thực hiện công việc và đặt lại dấu thời gian "lần chạy cuối cùng".

(* chỉ báo có dấu thời gian đó là một chút trạng thái tồn tại mà bạn có thể thao tác và kiểm tra, nhưng cron không thể)

** hãy cẩn thận với số học thời gian nếu bạn đang sử dụng đồng hồ có thể đọc được của con người - hai lần một năm, một số ngày có 23 hoặc 25 giờ trong ngày và 02: 00-02: 59 xảy ra hai lần trong một ngày hoặc không vào lúc tất cả. Sử dụng UTC để tránh điều này.


7
0 0 1-30/3 * *

Điều này sẽ chạy ba ngày một lần bắt đầu từ ngày 1. Đây là 20 lần chạy theo lịch trình -

  • 2015-06-01 00:00:00
  • 2015-06-04 00:00:00
  • 2015-06-07 00:00:00
  • 2015-06-10 00:00:00
  • 2015-06-13 00:00:00
  • 2015-06-16 00:00:00
  • 2015-06-19 00:00:00
  • 2015-06-22 00:00:00
  • 2015-06-25 00:00:00
  • 2015-06-28 00:00:00
  • 2015-07-01 00:00:00
  • 2015-07-04 00:00:00
  • 2015-07-07 00:00:00
  • 2015-07-10 00:00:00
  • 2015-07-13 00:00:00
  • 2015-07-16 00:00:00
  • 2015-07-19 00:00:00
  • 2015-07-22 00:00:00
  • 2015-07-25 00:00:00
  • 2015-07-28 00:00:00

5
2015-07-31 00:00:00, 2015-08-01 00:00:00 ... OOPS chỉ 1 ngày giữa các lần chạy
Dziamid

4

Tôi không nghĩ rằng bạn có những gì bạn cần với:

0 0 */3 * * ## <<< WARNING!!! CAUSES UNEVEN INTERVALS AT END OF MONTH!!

Thật không may, * / 3 là thiết lập khoảng thời gian trên mỗi ngày n thángkhông mỗi n ngày . Xem: giải thích tại đây . Vào cuối tháng, vấn đề định kỳ được đảm bảo.

1st  at 2019-02-01 00:00:00
then at 2019-02-04 00:00:00 << 3 days, etc. OK
then at 2019-02-07 00:00:00
...
then at 2019-02-25 00:00:00
then at 2019-01-28 00:00:00
then at 2019-03-01 00:00:00 << 1 day WRONG
then at 2019-03-04 00:00:00
...

Theo bài viết này , bạn cần thêm một số toán học modulo vào lệnh đang được thực thi để có được ĐÚNG "N ngày một lần". Ví dụ:

0 0 * * *  bash -c '(( $(date +\%s) / 86400 \% 3 == 0 )) && runmyjob.sh

Trong ví dụ này, công việc sẽ được kiểm tra hàng ngày lúc 12:00 sáng, nhưng sẽ chỉ thực hiện khi số ngày kể từ 01-01-1970 modulo 3 là 0.

Nếu bạn muốn đó là 3 ngày một lần kể từ một ngày cụ thể, hãy sử dụng định dạng sau:

0 0 * * *  bash -c '(( $(date +\%s -d "2019-01-01") / 86400 \% 3 == 0 )) && runmyjob.sh

3

Làm thế nào về:

00 00  *  *   * every 3 days && echo test

Trong trường hợp everylà một kịch bản:

#!/bin/sh

case $2 in
    days)
        expr `date +%j` % $1 = 0 > /dev/null
        ;;

    weeks)
        expr `date +%V` % $1 = 0 > /dev/null
        ;;

    months)
        expr `date +%m` % $1 = 0 > /dev/null
        ;;
esac

Vì vậy, nó chạy mỗi ngày.

Sử dụng */3chạy vào các ngày 3, 6, ... 27, 30 của tháng, nhưng sau đó bị sai sau một tháng có ngày thứ 31. Các everykịch bản chỉ là sai sau khi kết thúc năm.


3

Bạn nên tìm hiểu những điều cơ bản về crontab.

Chỉnh sửa cron bằng lệnh crontab -e, sau đó nhấn ⌃ (CTRL)+ Xsau đó Yvà cuối cùng nhấn ENTER (return)trên mac để lưu tệp. Bạn có thể kiểm tra xem các cây trồng mới đã được cài đặt chưa bởicrontab -l

Tệp crontab có năm trường để chỉ định phút, giờ, ngày trong tháng, tháng và ngày trong tuần, theo sau là lệnh sẽ được chạy trong khoảng thời gian đó.

*     *     *   *    *   command to be executed
-     -     -   -    -
|     |     |   |    |
|     |     |   |    +----- day of week (0-6) (Sunday=0)
|     |     |   +------- month (1-12)
|     |     +--------- day of month (1-31)
|     +----------- hour (0-23)
+------------- min (0-59)

* trong trường giá trị ở trên có nghĩa là tất cả các giá trị pháp lý như trong dấu ngoặc nhọn cho cột đó.

Ở đây, tôi đã viết một bài chi tiết về nó: Thiết lập Cron trong Unix


1

Sẽ đơn giản hơn nếu bạn định cấu hình nó chỉ chạy vào thứ hai và thứ năm, điều này sẽ giúp nó có thời gian nghỉ 3 và 4 ngày.

Nếu không, hãy định cấu hình nó để chạy hàng ngày, nhưng hãy làm cho tập lệnh php cron của bạn thoát sớm bằng:

if (! (date("z") % 3)) {
     exit;
}

0

Nếu bạn muốn nó chạy vào những ngày cụ thể trong tháng, như ngày 1, 4, 7, v.v. thì bạn chỉ cần có một điều kiện trong tập lệnh của mình để kiểm tra ngày hiện tại trong tháng.

Tôi nghĩ tất cả những gì bạn cần cho việc này là thay vì * / 3 có nghĩa là ba ngày một lần, hãy sử dụng 1/3 có nghĩa là ba ngày một lần bắt đầu từ ngày 1 của tháng. vì vậy 7/3 có nghĩa là ba ngày một lần bắt đầu từ ngày 7 của tháng, v.v.


0

0 0 * * * [ $(($((ngày +% - j- 1)) % 3)) == 0 ] && script

Lấy ngày trong năm từ đó date, bù với 1 để bắt đầu bằng 0, kiểm tra xem nó có phải là modulo ba hay không.


Sẽ không có trục trặc này khi nó chuyển từ năm không nhuận sang năm sau, vì ( 365-1 ) % 3 == 1nhưng ( 1 - 1 ) % 3 == 0? Tôi nghĩ rằng phép tính tốt hơn sẽ dựa trên số ngày kể từ Kỷ nguyên Unix.
kmoser
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.