ฉันจะเริ่ม cronjob ได้อย่างไร 1 ชั่วโมงต่อวันในแต่ละวัน?


16

ฉันต้องเริ่ม cronjob ทุกวัน แต่หนึ่งชั่วโมงต่อมาในแต่ละวัน สิ่งที่ฉันมีจนถึงตอนนี้ส่วนใหญ่ยกเว้น 1 วันของปี:

0 0 * * * sleep $((3600 * (10#$(date +\%j) \% 24))) && /usr/local/bin/myprog

เมื่อวันของปีคือ 365 งานจะเริ่มเวลา 5:00 น. แต่ในวันถัดไป (ไม่นับปีอธิกสุรทิน) จะมีวันของปีเป็น 1 ดังนั้นงานจะเริ่มเวลา 1:00 ฉันจะกำจัดตัวเรือนมุมนี้ได้อย่างไร


1
เหตุผลใดที่ไม่เพียงแค่เริ่มต้นทุก ๆ 25 ชั่วโมง?
HalosGhost

7
แล้วคุณจะทำอย่างไร * / 25 ในตำแหน่งชั่วโมงจะไม่แก้ปัญหา
เบิร์ช

@ HalosGhost ขอบคุณสำหรับคำแนะนำของคุณ! ฉันเขียนการใช้งานง่าย ๆ ตามที่
Giulio Muscarello

คำตอบ:


23

โซลูชันที่ฉันต้องการจะเริ่มงานทุกชั่วโมง แต่ให้สคริปต์ตรวจสอบตัวเองว่าถึงเวลาทำงานหรือไม่แล้วออกโดยไม่ทำอะไรเลย 24 ครั้งจาก 25 ครั้ง

crontab:

0 * * * *    /usr/local/bin/myprog

ที่ด้านบนของmyprog:

[ 0 -eq $(( $(date +%s) / 3600 % 25 )) ] || exit 0

หากคุณไม่ต้องการทำการเปลี่ยนแปลงใด ๆ กับสคริปต์คุณสามารถใส่ "เวลาในการรัน" ในรายการ crontab แต่จะทำให้เป็นบรรทัดที่ไม่น่าดูเป็นเวลานาน:

0 * * * *    [ 0 -eq $(( $(date +\%s) / 3600 \% 25 )) ] && /usr/local/bin/myprog

1
จำเป็นต้องหลบหนีด้วยแบ็กสแลชใน crontab
เบิร์ช

@ เบิร์ชฉันไม่เคยรู้ว่า! ฉันเดาว่าฉันไม่เคยลองรวม% ใน crontab มาก่อน ขอบคุณสำหรับการแก้ไขฉันได้แก้ไขคำตอบแล้ว
Celada

1
มันดูดีสำหรับฉัน ฉันไม่รู้ว่า OP ต้องการทำอะไรเกี่ยวกับเวลาออมแสง (เลื่อนไปข้างหน้าตกหลัง) แต่ OP ควรปรับตามนั้น
emory

ฉันกังวลเล็กน้อยเกี่ยวกับการปัดเศษในแผนก ถ้าด้วยเหตุผลบางอย่างเวลาที่dateกลับมาจากเคอร์เนลคือ1msก่อนเวลาที่คุณคาดว่าสคริปต์จะทำงานการตรวจสอบจะให้ผลลัพธ์ที่ไม่ถูกต้อง
kasperd

1
@kasperd ฉันไม่รู้ฉันคิดว่าคุณอาจพูดถูกเกี่ยวกับซีพียูที่แตกต่างกันที่รายงานเวลาต่างกัน สำหรับntpdมันจะพยายามอย่างหนักที่จะฆ่านาฬิกาไม่กระโดดโดยเฉพาะเพื่อหลีกเลี่ยงปัญหาแบบนี้ แต่คุณพูดถูกntpdateบางครั้ง(หรือ) บางครั้งก็สามารถกระโดดย้อนเวลากลับไปได้ สำหรับการcronคาดคะเนการหน่วงเวลาการนอนของมันฉันค่อนข้างแน่ใจว่าจะถือว่าเป็นข้อผิดพลาด! ยังคงจุดและวิธีแก้ปัญหาคือการกำหนดเวลางาน 30 นาทีที่ผ่านมาชั่วโมงซึ่งมีโอกาสน้อยที่จะทำให้เกิดปัญหา ... หรือเพิ่ม± 1800 ในการแสดงออกทางคณิตศาสตร์ก่อนที่จะใช้ mod reamainder 3600
Celada

7

หากระบบของคุณมี systemd คุณสามารถใช้เหตุการณ์ตัวจับเวลาสำหรับสิ่งนี้ เพียงกำหนดบริการใหม่ซึ่งควรมีคำสั่ง / งานที่คุณต้องการดำเนินการแล้วสร้างเหตุการณ์ตัวจับเวลาด้วยOnUnitActiveSecตัวเลือก:

[Unit]
Description=daily + 1 hour task

[Timer]
OnUnitActiveSec=25h # run 25 hours after service was last started
AccuracySec=10min

[Install]
WantedBy=timers.target

ใช้ชื่อเดียวกันสำหรับไฟล์ยกเว้นว่า.serviceคุณจะใช้.timerแทน

การสังเคราะห์:

  1. สร้างไฟล์ที่เรียกว่าjob.serviceใน/etc/systemd/system/ไดเรกทอรี
  2. กรอกข้อมูลที่จำเป็น systemctl status job.serviceคุณสามารถตรวจสอบการตั้งค่าการใช้
  3. สร้างไฟล์ที่เรียกว่าในjob.timer/etc/systemd/system/
  4. กรอกข้อมูลที่จำเป็น:

    [Unit]
    Description=daily + 1 hour task
    
    [Timer]
    OnUnitActiveSec=25h # run 25 hours after service was last started
    AccuracySec=10min
    
    [Install]
    WantedBy=timers.target
    
  5. ตรวจสอบตัวจับเวลาโดยใช้ systemctl list-timers
  6. เสร็จสิ้น

ถ้าฉันจะหลงทางจากความเรียบง่ายของ cron ฉันจะใช้ launchd ซึ่งจะต้องใช้งานน้อยกว่าตัวอย่างของคุณสำหรับ systemd
เบิร์ช

6

หากคุณไม่ทราบใช้สิ่งอื่นนอกเหนือจาก cronjobs atผมจะแนะนำยูทิลิตี้ไม่ค่อยมีคนรู้จัก เพียงเขียนสคริปต์ตัวตัดคำที่กำหนดเวลาให้ตัวเองทำงานใน 25 ชั่วโมงจากนั้นเรียกโปรแกรมของคุณ นี่น่าจะเป็นทางออกที่สะอาดที่สุด
ตัวอย่างเช่นคุณสามารถเขียนสิ่งนี้ใน ~ / script.sh:

echo "bash ~/script.sh" | at now + 25 hours
/usr/bin/yourprogram

จากนั้นเรียกใช้เพียงbash ~/script.shครั้งเดียว

ขอบคุณ @HalosGhost สำหรับแนวคิดของการจัดตารางเวลางานหนึ่งครั้งใน 25 ชั่วโมง


2
มีปัญหา 2 ข้อในการใช้atเพื่อจุดประสงค์นี้: (1) หากงานล้มเหลวในการดำเนินการอย่างถูกต้องแม้แต่ครั้งเดียวก็อาจล้มเหลวในการกำหนดเวลาใหม่เองและไม่ใช่แค่การดำเนินการครั้งต่อไป แต่การประหารชีวิตในอนาคตทั้งหมดจะถูกยกเลิกอย่างมีประสิทธิภาพ (2) เนื่องจากงานใช้เวลาที่ไม่เป็นศูนย์ในการรันโดยใช้ความไร้เดียงสาnow + 25 hoursหมายความว่ามันจะทำงานสองสามวินาที (หรือมากกว่า) ในแต่ละครั้งในภายหลังความล่าช้านี้จะเพิ่มขึ้นเมื่อเวลาผ่านไป เวลา.
Celada

2
คุณถูกต้องเกี่ยวกับ # 1; ฉันไม่แน่ใจเกี่ยวกับ # 2 แม้ว่าฉันจะไม่มีข้อมูลใด ๆ แต่ฉันไม่คิดว่าความล่าช้าระหว่างการเปลี่ยนนาฬิกาและการทำงานที่ถูกกระตุ้นและกำหนดเวลาใหม่นั้นมีขนาดใหญ่พอที่จะสังเกตได้ - โดยเฉพาะอย่างยิ่งเมื่อพิจารณาว่าความละเอียดของatจำกัด เพียงไม่กี่นาทีและเริ่มงานทั้งหมด ที่ [เวลา]: 00
Giulio Muscarello

1
@Celada: การกำหนดเวลาatงานถัดไปสิ่งแรกใน at at script หลีกเลี่ยงปัญหาเหล่านั้น อย่างไรก็ตามหากเกิดข้อผิดพลาดโซ่ทั้งหมดจะเสียหายซึ่งอาจจะหรืออาจไม่เป็นที่ต้องการ: ถ้ากรณีการใช้งานคือ "เรียกใช้สิ่งนี้เมื่อทำงาน" เท่านั้นการเริ่มใหม่เป็นคุณสมบัติที่ยอดเยี่ยม แต่ถ้ากรณีการใช้งานเป็น "เรียกใช้เสมอแม้ว่าความล้มเหลวครั้งสุดท้าย" ก็atไม่ใช่เครื่องมือที่เหมาะสม
อธิการ
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.