นอนจนกว่าจะถึงเวลาต่อไปตามเวลาที่กำหนด


11

ฉันต้องการชุดคำสั่งหรือคำสั่งเดียวที่หลับจนกว่าจะเกิดเหตุการณ์ต่อไปของเวลาเฉพาะเช่น "4:00"

ฉันจะทำอย่างไร

atคำสั่งหรือ cronjob ไม่ได้เป็นตัวเลือกเพราะผมไม่ต้องออกจากสคริปต์ที่ผมในปัจจุบัน

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

มันจะเป็นประโยชน์อย่างมากหากสคริปต์จะต้องสร้างไฟล์ใด ๆ หรืองานอื่น ๆ เช่น cronjobs หรือหน้าจออื่น ๆ นี่เป็นเพียงคำถามของการออกแบบ

ฉันเพิ่งมีความคิดที่น่ากลัว:

difference=$(($(date -d "4:00" +%s) - $(date +%s)))

if [ $difference -lt 0 ]
then
    sleep $((86400 + difference))
else
    sleep $difference
fi

คุณมีความคิดที่ดีกว่านี้ไหม?

ข้อมูลเพิ่มเติมจะถูกเพิ่มหากมีการร้องขอ!


โปรดอธิบายคำถามของคุณหน่อยได้ไหม? คุณหมายถึงอะไรเมื่อคุณพูดว่า: "ฉันต้องไม่ทิ้งสคริปต์ที่ฉันกำลังอยู่"
sebelk

คุณมีการตรวจสอบสคริปต์ของคุณเกี่ยวกับไฟล์ "ปลุก" และพักเป็นระยะเวลาหนึ่งก่อนที่จะตรวจสอบอีกครั้งหรือไม่ จากนั้นคุณสามารถใช้ cron เพื่อสร้างไฟล์ใช้ประโยชน์จากความน่าเชื่อถือของ cron แต่คุณสามารถมีสคริปต์ที่ยาวนานของคุณได้เช่นกัน เพียงแค่ให้สคริปต์ลบไฟล์ "ปลุก" เมื่อมันหยุดหลับ
kurtm

โปรดทราบว่าบน Mac คุณควรเปลี่ยนdate -dด้วยdate -jและแทนที่ด้วย4:00 0400
pjvandehaar

คำตอบ:


17

ข้อเสนอแนะของ terdon จะใช้ได้ แต่ฉันคิดว่าของฉันมีประสิทธิภาพมากกว่า

difference=$(($(date -d "4:00" +%s) - $(date +%s)))

if [ $difference -lt 0 ]
then
    sleep $((86400 + difference))
else
    sleep $difference
fi

นี่เป็นการคำนวณความแตกต่างระหว่างเวลาที่กำหนดและเวลาปัจจุบันเป็นวินาที หากจำนวนเป็นลบเราต้องเพิ่มวินาทีสำหรับทั้งวัน (86400 เป็นที่แน่นอน) เพื่อให้ได้วินาทีที่เราต้องนอนหลับและถ้าจำนวนนั้นเป็น postive เราก็สามารถใช้มันได้


จะเกิดอะไรขึ้นถ้านาฬิกาของระบบเลื่อนไปข้างหน้า / ถอยหลัง (เช่น: ntp)
WhyNotHugo

10

สมมติว่ามันเป็นเชลล์สคริปต์สิ่งนี้ควรใช้งานได้:

while [ $(date +%H:%M) != "04:00" ]; do sleep 1; done

นั่นเป็นเวลา 24 ชั่วโมง หากคุณต้องการให้สิ่งนี้ดำเนินการต่อทั้งเวลา 4:00 น. และ 16:00 น. ให้ใช้สิ่งนี้แทน:

while [ $(date +%I:%M) != "04:00" ]; do sleep 1; done

นี่อาจเป็นตัวเลือก ฉันเพิ่งมีความคิด ฉันจะกลับมาอีกในไม่กี่นาที
BrainStone

0

บนOpenBSDข้อมูลต่อไปนี้สามารถใช้ในการกระชับงาน*/55 นาทีcrontab(5)เป็น00รายชั่วโมง (เพื่อให้แน่ใจว่ามีการสร้างอีเมลน้อยลงทั้งหมดในขณะที่ปฏิบัติงานเดียวกันตามช่วงเวลาที่แน่นอน):

#!/bin/sh -x
for k in $(jot 12 00 55)
  do
  echo $(date) doing stuff
  sleep $(expr $(date -j +%s $(printf %02d $(expr $k + 5))) - $(date -j +%s))
done

โปรดทราบว่าสิ่งที่date(1)จะทำลายsleep(1)โดยการออกแบบในการทำซ้ำขั้นสุดท้ายเนื่องจาก60นาทีไม่ใช่เวลาที่ถูกต้อง (เว้นแต่จะเป็น!) ดังนั้นเราจึงไม่ต้องรอเวลาเพิ่มเติมก่อนที่จะได้รับรายงานทางอีเมลของเรา

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

printf(1)เป็นสิ่งจำเป็นเพราะdateคาดว่าตัวเลขสองหลักสำหรับสเปคนาที

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.