งาน Cron ทุกสามวัน


97

เป็นไปได้ไหมที่จะเรียกใช้cronjobทุกสามวัน? หรืออาจจะ 10 ครั้ง / เดือน.


4
ใช่มันเป็นไปได้และสิ่งนี้เป็นของ SuperUser

การวิ่งทุกๆ 3 วันโดยไม่คำนึงถึงขอบเขตของเดือนสามารถทำได้ด้วย anacron
ryanpattison

คำตอบ:


133

เรียกใช้ทุกสามวัน ...

0 0 */3 * *

อย่างนั้นเหรอ?

หากคุณต้องการให้มันทำงานในวันที่เฉพาะเจาะจงของเดือนเช่นวันที่ 1, 4, 7 เป็นต้น ... คุณก็สามารถมีเงื่อนไขในสคริปต์ของคุณที่ตรวจสอบวันปัจจุบันของเดือน

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

หรือตามที่ @mario ชี้ให้เห็นคุณสามารถใช้วันที่ ('k') เพื่อรับวันของปีแทนที่จะทำตามวันของเดือน


9
@whatshakin: มันจะขึ้นอยู่กับว่าคุณต้องการให้ "ทุกๆสามวัน" เป็นอย่างไร สิ่งนี้จะใช้ได้ในวันใดก็ได้ที่หารด้วย 3 ลงตัวในขอบเขตเดือนมันจะไม่แน่นอน
เดวิด

3
@whatshakin: ไวยากรณ์ cronjob อธิบายไว้ใน Wikipedia: en.wikipedia.org/wiki/Cronjob
Felix Kling

4
นี่เป็นผลลัพธ์ที่สูงมากใน google และด้วยเหตุนี้มันจะดีกว่าถ้าคำตอบที่ยอมรับนั้นถูกต้องซึ่งไม่ใช่ ฉันเชื่อว่าคำอธิบายของ Tareco ถูกต้อง
lynks

14
คำตอบไม่ถูกต้องเนื่องจากข้อเสนอแนะทั้งสองไม่ทำงานทุก 3 วัน 0 0 */3 * *หมายถึงวิ่งในวันที่ 1, 4, 7 เป็นต้น ( */3หมาย1-31/3ถึง1,4,7...31) ดังนั้นช่องว่างจะเล็กลงเมื่อสิ้นเดือน (มันจะทำงาน 2 วันติดกันถ้าเดือนก่อนหน้ามี 31 วัน) date('j') % 3ปัญหาที่คล้ายกันคือรูปแบบเริ่มต้นใหม่ทุกปีและปีไม่มีจำนวนวันหารด้วย 3
cjm

8
ฉันรู้สึกว่ามันโชคร้ายเกินไปที่สิ่งนี้ได้รับการยอมรับว่าเป็นคำตอบ ฉันมองหาทุกๆ N วันโดยไม่คำนึงถึงขอบเขตของเดือน (สิ่งต่างๆเช่นพืชไม่สนใจว่าพวกเขาจะได้รับน้ำในวันใดของเดือน) อย่างน้อยฉันคิดว่าฉันตัดสินใจหลังจากอ่านความคิดเห็นทั้งหมดแล้วว่าตัวจับเวลา cron ไม่ได้จำลองแบบความต้องการนั้นอย่างเต็มที่
Travis Griggs

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

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

ขอบคุณคำอธิบาย
pythonian29033

2
โดยปกติจะยิงทุกสามวัน แต่สามารถยิงได้ในวันถัดไปต้นเดือน
Dziamid

25

ฉันไม่ใช่ผู้เชี่ยวชาญ cron แต่เกี่ยวกับ:

0 */72 * * *

จะทำงานทุก 72 ชั่วโมงโดยไม่ถูกขัดจังหวะ

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


3
มีความแม่นยำมากกว่าโซลูชันที่ยอมรับ คำตอบที่ยอมรับจะล้มเหลวเมื่อเปลี่ยนเดือน:then at 2019-02-28 00:00:00 then at 2019-03-01 00:00:00
Akira Yamamoto

3
ตามcrontab.guruนี้ทำงานทุกวัน ใครถูก?
velop

2
ค่าในคอลัมน์ชั่วโมงต้องอยู่ระหว่าง 0 และ 23 ตามcrontab.guruและคน crontab
harperville

2
* / 72 มีประสิทธิภาพเหมือนกับ 0 ซึ่งจะทำงานทุกเที่ยงคืน
Battey

3
ฉันทดสอบสิ่งนี้ มันทำงานทุกวัน
Ali Azhar

19

เนื่องจาก cron เป็น "ไร้สัญชาติ" จึงไม่สามารถแสดง "ความถี่" ได้อย่างถูกต้องมีเพียง "รูปแบบ" ที่ (เห็นได้ชัด) ซึ่งตรงกับเวลาปัจจุบันอย่างต่อเนื่อง

การเปลี่ยนประโยคคำถามของคุณทำให้ชัดเจนขึ้น: "เป็นไปได้ไหมที่จะเรียกใช้ cronjob เวลา 00:01 น. ทุกคืนยกเว้นข้ามคืนเมื่อดำเนินการภายใน 2 คืน" เมื่อ cron กำลังเปรียบเทียบเวลาปัจจุบันกับรูปแบบเวลาของานไม่มีทางที่ cron จะรู้ได้ว่ามันทำงานของคุณในอดีตหรือไม่

โดยปกติคุณจะต้องยุติเหตุการณ์ที่เกิดซ้ำนั้นและรีสตาร์ทเหตุการณ์ใหม่ทั้งหมด สิ่งนี้แสดงให้เห็นถึงการแสดงออกที่ จำกัด ว่าแอปปฏิทินที่ซับซ้อนแสดงถึงรูปแบบการทำซ้ำได้อย่างไร และแน่นอนว่าปฏิทินมีหลายสถานะ - แต่ละกิจกรรมสามารถลบหรือกำหนดเวลาใหม่ได้โดยอิสระ [ในแอปปฏิทินส่วนใหญ่])

นอกจากนี้คุณอาจต้องการทำงานของคุณทุกคืนที่ 3 หากประสบความสำเร็จแต่ถ้าสุดท้ายล้มเหลวให้ลองอีกครั้งในทันทีบางทีในคืนถัดไป (อย่ารออีก 3 วัน) หรือเร็วกว่านั้นเช่นหนึ่งชั่วโมงต่อมา (แต่ให้หยุดลองใหม่ เมื่อมาถึงตอนเช้า) เห็นได้ชัดว่า cron ไม่สามารถทราบได้ว่างานของคุณประสบความสำเร็จหรือไม่และรูปแบบดังกล่าวไม่สามารถแสดงกำหนดการ "ลองใหม่" ที่ใช้บ่อยกว่า

อย่างไรก็ตาม - คุณสามารถทำสิ่งที่คุณต้องการได้ด้วยตัวเอง เขียนสคริปต์บอก cron ให้เรียกใช้ทุกคืนเวลา 00:01 น. สคริปต์นี้สามารถตรวจสอบการประทับเวลาของบางสิ่งบางอย่าง * ซึ่งบันทึก "การรันครั้งสุดท้าย" และหากเป็นเวลา> 3 วันที่ผ่านมา ** ให้ดำเนินการและรีเซ็ตการประทับเวลา "รันครั้งสุดท้าย"

(* ตัวบ่งชี้ที่ประทับเวลานั้นเป็นสถานะที่คงอยู่ซึ่งคุณสามารถจัดการและตรวจสอบได้ แต่ cron ตัวใดไม่สามารถทำได้)

** โปรดใช้ความระมัดระวังในการคำนวณเวลาหากคุณใช้เวลานาฬิกาที่มนุษย์อ่านได้ปีละสองครั้งบางวันมี 23 หรือ 25 ชั่วโมงในแต่ละวันและ 02: 00-02: 59 เกิดขึ้นสองครั้งในหนึ่งวันหรือไม่ ทั้งหมด. ใช้ UTC เพื่อหลีกเลี่ยงปัญหานี้


7
0 0 1-30/3 * *

การดำเนินการนี้จะทำงานทุกสามวันเริ่มตั้งแต่วันที่ 1 นี่คือกำหนดการวิ่ง 20 รายการ -

  • 2015-06-01 00:00:00 น
  • 2015-06-04 00:00:00 น
  • 2015-06-07 00:00:00 น
  • 2015-06-10 00:00:00 น
  • 2558-06-13 00:00:00 น
  • 2558-06-16 00:00:00 น
  • 2558-06-19 00:00:00 น
  • 2558-06-22 00:00:00 น
  • 2558-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 น
  • 2558-07-19 00:00:00 น
  • 2558-07-22 00:00:00 น
  • 2558-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 เพียง 1 วันระหว่างการวิ่ง
Dziamid

6

ฉันไม่คิดว่าคุณมีสิ่งที่คุณต้องการด้วย:

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

แต่น่าเสียดายที่ * / 3 คือการตั้งค่าช่วงเวลาในทุกวัน n ของเดือนและไม่ได้ ทุกวันที่ n ดู: คำอธิบายที่นี่ ในตอนท้ายของเดือนมีการรับประกันปัญหาที่เกิดซ้ำ

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
...

ตามบทความนี้คุณต้องเพิ่มคณิตศาสตร์โมดูโลในคำสั่งที่กำลังดำเนินการเพื่อให้ได้ค่า TRUE "ทุก N วัน" ตัวอย่างเช่น:

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

ในตัวอย่างนี้งานจะถูกตรวจสอบทุกวันเวลา 00.00 น. แต่จะดำเนินการก็ต่อเมื่อจำนวนวันตั้งแต่ 01-01-1970 โมดูโล 3 เป็น 0

หากคุณต้องการให้เป็นทุก 3 วันนับจากวันที่ระบุให้ใช้รูปแบบต่อไปนี้:

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

คำพูดเดียวนั้นควรจะสมดุลกันหรือไม่?
Ken Ingram

3

เกี่ยวกับ:

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

everyสคริปต์อยู่ที่ไหน:

#!/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

มันจึงทำงานทุกวัน

ใช้*/3รันในวันที่ 3, 6, ... 27, 30 ของเดือน แต่ผิดพลาดหลังจากเดือนมีวันที่ 31 everyสคริปต์เป็นเพียงที่ไม่ถูกต้องหลังจากการสิ้นสุดของปี


3

คุณควรเรียนรู้พื้นฐานของcrontab.

แก้ไข cron ตามคำสั่งcrontab -eจากนั้น⌃ (CTRL)+ Xจากนั้นYกดENTER (return)บน mac เพื่อบันทึกไฟล์ คุณสามารถตรวจสอบ crons ใหม่ได้รับการติดตั้งโดยไม่crontab -l

ไฟล์ crontab มีห้าฟิลด์สำหรับระบุนาทีชั่วโมงวันของเดือนเดือนและวันในสัปดาห์ตามด้วยคำสั่งที่จะรันในช่วงเวลานั้น

*     *     *   *    *   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)

* ในฟิลด์ค่าด้านบนหมายถึงค่าทางกฎหมายทั้งหมดเช่นเดียวกับในวงเล็บปีกกาสำหรับคอลัมน์นั้น

ที่นี่ฉันเขียนโพสต์โดยละเอียดเกี่ยวกับเรื่องนี้: ตั้งค่า Cron ใน Unix


1

มันจะง่ายกว่าถ้าคุณกำหนดค่าให้เรียกใช้เช่นในวันจันทร์และวันพฤหัสบดีซึ่งจะให้เวลาพัก 3 และ 4 วัน

มิฉะนั้นกำหนดค่าให้ทำงานทุกวัน แต่ทำให้สคริปต์ php cron ของคุณออกก่อนเวลาด้วย:

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

0

หากคุณต้องการให้มันทำงานในวันที่เฉพาะเจาะจงของเดือนเช่นวันที่ 1, 4, 7 เป็นต้น ... คุณก็สามารถมีเงื่อนไขในสคริปต์ของคุณที่ตรวจสอบวันปัจจุบันของเดือน

ฉันคิดว่าสิ่งที่คุณต้องการสำหรับสิ่งนี้คือแทนที่จะเป็น * / 3 ซึ่งหมายความว่าทุกๆสามวันให้ใช้ 1/3 ซึ่งหมายถึงทุกๆสามวันเริ่มในวันที่ 1 ของเดือน ดังนั้น 7/3 จะหมายถึงทุกๆสามวันเริ่มในวันที่ 7 ของเดือนเป็นต้น


0

0 0 * * * [ $(($((วันที่ +% - ญ- 1)) % 3)) == 0 ] && script

รับวันของปีจากdateนั้นชดเชยด้วย 1 เพื่อเริ่มต้นที่ 0 ตรวจสอบว่าเป็นโมดูโล 3 หรือไม่


สิ่งนี้จะไม่สะอึกเมื่อมันเปลี่ยนจากปีที่ไม่ใช่ปีอธิกสุรทินไปเป็นปีหน้า( 365-1 ) % 3 == 1แต่ ( 1 - 1 ) % 3 == 0? ฉันคิดว่าการคำนวณที่ดีขึ้นจะขึ้นอยู่กับจำนวนวันนับตั้งแต่ Unix Epoch
kmoser
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.