ฉันสามารถทำงาน cron บ่อยกว่าทุกนาทีได้หรือไม่?


43

เป็นไปได้ไหมที่จะรันงาน cron ทุก ๆ 30 วินาทีโดยไม่มีคำสั่ง sleep?


4
คุณตั้งใจทำอะไร cron เป็นเครื่องมือที่เหมาะสมที่จะใช้กับสิ่งนี้หรือไม่?
Manuel Faux

คำถามที่ดี.
Preet Sangha

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

คำตอบ:


36

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


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

2
ฉันหมายถึงถ้าคุณไม่ใช้ pidfile หากงานของคุณทำงานทุก ๆ X นาทีและใช้เวลานานกว่า X นาทีในการดำเนินการจนเสร็จสิ้นคุณจะต้องจบงานด้วย หากงานของคุณถูก จำกัด ด้วยทรัพยากรบางประเภท (CPU, เครือข่าย / แบนด์วิดท์ดิสก์ ฯลฯ ) การทำงานมากกว่าหนึ่งครั้งจะทำให้งานเสร็จสิ้นได้นานขึ้นและในที่สุดคอมพิวเตอร์ของคุณจะกลายเป็นเรื่องวุ่นวาย
duskwuff

2
คุณสามารถใช้run-oneเพื่อให้แน่ใจว่าโปรแกรม / แม้กระทั่งสคริปต์ PHP ไม่ได้เริ่มต้นอินสแตนซ์ที่ซ้ำกัน sudo apt-get install run-oneและเรียกมันโดยrun-one <normal command>
kouton

3
ในฐานะที่เป็นคำตอบต่อไปแสดงมันเป็นไปได้เป็นอย่างดีแม้ว่าบิตแฮ็ค ทำไมคุณถึงทำผิด !!!! คำตอบที่ยอมรับได้ที่นี่เมื่อไม่ตอบคำถามเลย?
คน

@Mantriur เพราะผู้เขียนคำถามพบว่ามีประโยชน์และทำเครื่องหมายว่าเป็นคำตอบที่ยอมรับได้หรือไม่ :) แต่อย่างจริงจังแม้ว่าคุณได้ระบุปัญหาด้วยตัวคุณเองแล้ว: คำตอบร่วมสมัยอื่น ๆ อีกมากมายที่นำเสนอวิธีแก้ไขปัญหาแฮ็กซึ่งจะไม่ฉลาดที่จะใช้ในระบบการผลิต (โปรดจำไว้ว่าคำตอบอื่น ๆ อีกมากมายปรากฏขึ้นหลังจากถามคำถามมาหลายปีเท่านั้นดังนั้นพวกเขาจึงยังไม่สามารถยอมรับได้!)
duskwuff

36

ผู้สมัครเพื่อการใช้งานอย่าง ผิดพลาดที่สุดของคำสั่ง Linux:

nohup watch -n 30 --precise yourprog >/dev/null &

ถ้าyourprogประกอบด้วย:

date +%M.%S.%N >> yourprog.out

จากนั้นyourprog.outอาจมีลักษณะเช่น:

50.51.857291267
51.21.840818353
51.51.840910204
52.21.840513307
52.51.842455224
53.21.841195858
53.51.841407587
54.21.840629676

บ่งบอกถึงระดับความแม่นยำที่ค่อนข้างดี

นี่คือคำอธิบายของส่วนต่าง ๆ ของคำสั่ง:

  • nohup- สิ่งนี้จะเก็บคำสั่งที่ตามมาwatchในกรณีนี้จากการออกเมื่อเทอร์มินัลออก
  • watch- โปรแกรมนี้รันคำสั่งซ้ำ ๆ โดยปกติหน้าจอแรกของเอาต์พุตจากคำสั่งจะถูกแสดงทุกครั้งที่watchรันคำสั่ง
  • -n 30- ช่วงเวลาที่เรียกใช้คำสั่ง ในกรณีนี้คือทุก ๆ สามสิบวินาที
  • --precise- หากไม่มีตัวเลือกนี้ให้watchรันคำสั่งหลังจาก ช่วงเวลาวินาที ด้วยคำสั่งเริ่มต้น แต่ละคำสั่งจะเริ่มต้นในช่วงเวลาถ้าเป็นไปได้ หากตัวเลือกนี้ไม่ได้ระบุไว้ในตัวอย่างเวลาจะได้รับในภายหลังและต่อมามากกว่า 30 วินาทีในแต่ละครั้งเนื่องจากเวลาที่จะเปิดตัวและดำเนินการคำสั่ง ( yourprog)
  • yourprog- โปรแกรมหรือบรรทัดคำสั่งสำหรับwatchการดำเนินการ หากบรรทัดคำสั่งมีอักขระพิเศษสำหรับเชลล์ (เช่น space หรือเซมิโคลอน) จะต้องมีการเสนอราคา
  • >/dev/null- ยิ่งกว่าการเปลี่ยนเส้นทางการส่งออกของคำสั่งที่ถูกเรียกใช้โดยไปยังแฟ้มwatch /dev/nullไฟล์นั้นจะทิ้งข้อมูลใด ๆ ที่ถูกเขียนไป นี้จะช่วยป้องกันการส่งออกจากการถูกเขียนไปยังหน้าจอหรือตั้งแต่มีการใช้จะป้องกันไม่ให้เอาท์พุทจากการถูกส่งไปยังไฟล์ที่เรียกว่าnohupnohup.out
  • &- watchคำสั่งรันในพื้นหลังและการควบคุมจะถูกส่งกลับไปยังเทอร์มินัลหรือกระบวนการหลัก

โปรดทราบว่าการnohupเปลี่ยนเส้นทางของการส่งออกและการที่ผู้ประกอบการควบคุมพื้นหลังไม่ได้เฉพาะเจาะจงกับ&watch

นี่คือคำอธิบายของyourprogสคริปต์ตัวอย่าง:

  • date- ส่งออกวันที่และ / หรือเวลาปัจจุบัน นอกจากนี้ยังสามารถตั้งค่าได้
  • +%M.%S.%N- สิ่งนี้ระบุรูปแบบผลลัพธ์ที่dateจะใช้ %Mคือนาทีปัจจุบัน%Sเป็นวินาทีปัจจุบันและ%Nเป็น nanosecond ปัจจุบัน
  • >> yourprog.out- นี้เปลี่ยนเส้นทางการส่งออกของคำสั่งไปยังไฟล์ที่เรียกว่าdate yourprog.outยิ่งใหญ่กว่าเป็นสองเท่าทำให้เอาต์พุตถูกผนวกเข้ากับไฟล์ในแต่ละการเรียกใช้แทนที่จะเป็นเนื้อหาก่อนหน้านี้ที่ถูกเขียนทับ

แก้ไข :

อาจเป็นอีกสิ่งหนึ่งที่อาจถูกทารุณกรรม (หรืออาจเป็นการใช้ที่ถูกกฎหมาย) คือตัวจับเวลา systemd

ดูsystemd / ตัวจับเวลาแทน cronและCron VS จับเวลา

ฉันจะลองโพสต์ตัวอย่างเร็ว ๆ นี้


6
ฉันให้ +1 สำหรับแก้มบริสุทธิ์
แมตต์ซิมมอนส์

2
ยินดีที่ได้รับคำอธิบายเพิ่มเติมเล็กน้อยจากคำตอบนี้ คำสั่ง nohup เป็นของใหม่สำหรับฉัน อินเทอร์เน็ตบอกฉันว่ามันคือการไม่สนใจสัญญาณ Hangup ซึ่งยังทำให้ฉันสับสน
donquixote

2
@donquixote: มันเป็นสิ่งสำคัญที่ต้องตระหนักว่าคำสั่งโดยรวมในคำตอบของฉันไม่ได้เป็นสิ่งที่แนะนำให้ทำดังนั้นการใช้คำว่า "ผิด" อย่างไรก็ตามเพื่อชี้แจงสิ่งต่าง ๆ ให้คุณเล็กน้อยเนื่องจากมีเทคนิคที่มีประโยชน์รวมอยู่ด้วยฉันจะพยายามอธิบายบางอย่าง &สาเหตุของคำสั่งที่จะทำงานในพื้นหลังกลับการควบคุมคำสั่งพร้อมรับคำทันที การใช้nohupคำสั่งทำให้กระบวนการที่อยู่เบื้องหลัง (ในกรณีนี้watch) ละเว้นสัญญาณ Hangup ที่ส่งเมื่อเชลล์ออกเช่นเมื่อคุณปิดเทอร์มินัล ...
Dennis Williamson

1
... การเปลี่ยนทิศทางเอาต์พุตโดยใช้>/dev/nullสาเหตุทำให้เอาต์พุตถูกยกเลิกและป้องกันการสร้างnohup.outไฟล์ซึ่งจะถูกสร้างขึ้นเมื่อเอาต์พุตมาตรฐานเป็นเทอร์มินัล
Dennis Williamson

1
@donquixote: ไม่ใช่แค่ 30 วินาทีต่อจากนี้ทุก ๆ 30 วินาที ส่วนที่เหลือคือการให้มันทำงานแบบไม่ต้องใส่ข้อมูลในพื้นหลังเพื่อให้เหมือน cron มากขึ้น หากคุณต้องการใช้sleepคุณจะต้องเขียนวนซ้ำเพื่อให้กระบวนการทำซ้ำ ( watchนี่จะเป็นการทำซ้ำสำหรับคุณเช่นเดียวกับcron) คุณยังคงต้องและnohup &ปัญหาที่เพิ่มเข้ามาsleepคือการเลื่อนเวลา --preciseตัวเลือกในการwatchหลีกเลี่ยงนี้ หากไม่มีมันหรือเมื่อใช้sleepในการวนรอบช่วงเวลาจะมีเวลาสำหรับคำสั่งหรือสคริปต์ที่จะเรียกใช้เพิ่มเข้าไปดังนั้นแต่ละการเรียกใช้จะได้รับในภายหลังและหลังจาก ...
Dennis Williamson

13

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


10
* * * * * /path/to/program
* * * * * sleep 30; /path/to/program

อย่าลืมที่จะเขียนบางสิ่งบางอย่างลงในโปรแกรมของคุณเพื่อให้มันออกหากอินสแตนซ์ก่อนหน้านี้ทำงานอยู่

#!/bin/sh

if ln -s "pid=$$" /var/pid/myscript.pid; then
  trap "rm /var/pid/myscript.pid" 0 1 2 3 15
else
  echo "Already running, or stale lockfile." >&2
  exit 1
fi

แน่นอนว่านี่ยังทำให้โอกาสในการล้มเหลวมีน้อยมากดังนั้นให้ค้นหา google เพื่อหาทางออกที่ดีกว่าสำหรับสภาพแวดล้อมของคุณ


มันได้รับการถามว่า:without a sleep command
ฟิลิปป์

10
ผู้เข้าชมอื่น ๆ หาคำถามนี้ไม่สนใจว่าคำสั่งการนอนหลับจะใช้ :)
donquixote

8

คุณสามารถทำได้ด้วยซอฟต์แวร์บุคคลที่สาม

ตัวเลือกที่ทำงานได้ดีสำหรับฉันคือcron บ่อย

จะช่วยให้ความแม่นยำมิลลิวินาทีและให้คุณเลือกที่จะชะลอการดำเนินการต่อไปจนกว่าจะมีการออกในปัจจุบัน ..


1
cron ที่ใช้งานบ่อยก็ทำงานได้ดีสำหรับเราเช่นกันและสนับสนุนระบบการผลิตของเรามากมาย เราไม่เคยมีปัญหากับมัน
Homer6

2

ฉันมีข้อกังวลสองสามข้อ:

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

(2) สคริปต์อาจมีโอเวอร์เฮดจำนวนมากและใช้ทรัพยากรระบบมากกว่าที่คุณต้องการ สิ่งนี้เป็นจริงถ้าคุณแข่งขันกับกิจกรรมของระบบอื่น ๆ มากมาย

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


1

ทางออกที่ง่ายและโปรดปรานที่สุดสำหรับงานนี้:

รายการ cron:
* * * * * flock -w0 /path/to/script /path/to/script

สคริปต์:
while true;do echo doing something; sleep 10s;done

ทางเลือกที่ขี้เกียจ: :)

* * * * * flock -w0 /path/to/log watch -n 10 echo doing >> /path/to/log

หรือ

* * * * * flock -w0 /path/to/log watch -n 10 /path/to/script

ข้อดี

  • การใช้flockคำสั่งหลีกเลี่ยงการเรียกใช้สคริปต์จากหลาย ๆ อินสแตนซ์ในเวลาเดียวกัน อาจมีความสำคัญมากในกรณีส่วนใหญ่
  • flockและwatchคำสั่งนั้นมีอยู่ในการติดตั้ง Linux ส่วนใหญ่

ข้อเสีย

  • การหยุด "บริการ" ประเภทนี้ต้องใช้สองขั้นตอน
    • คอมเม้นต์รายการ cron
    • ฆ่าสคริปต์หรือwatchคำสั่ง

2
ใครสามารถกรุณาอธิบายสิ่งนี้กับมือใหม่ที่ใช้ linux - ด้วยข้อดีข้อเสีย? ขอบคุณ ..
a20

@ asvany ฉันคิดว่าฉันชอบวิธีนี้ แต่เป็น a20 คุณช่วยโพสต์คำอธิบายสำหรับ Linux "สีเขียว" ได้มั้ย TY
JoelAZ

0

วิธีแก้ปัญหาถ้าเป็นเพื่อสคริปต์ของคุณเองหรือถ้าคุณสามารถสรุปได้:

  1. รับและจดจำเวลาเริ่มต้น
  2. หากมีไฟล์ล็อคที่คุณจะสัมผัสในภายหลังและสคริปต์ไม่ได้ทำงานเป็นเวลา 60 วินาทีให้รอสักครู่แล้วตรวจสอบอีกครั้ง (เช่นในขณะที่ / นอนหลับ) *
  3. หากไฟล์ล็อคยังคงปรากฏหลังจากผ่านไป 60 วินาทีให้ออกโดยมีคำเตือนล็อคเก่า
  4. แตะล็อคไฟล์
  5. ในขณะที่สคริปต์ไม่ได้ทำงานเป็นเวลา 60 วินาทีให้วนลูปงานจริงของคุณด้วยระยะเวลาสลีปที่ต้องการ
  6. ลบไฟล์ล็อค
  7. เพิ่มเป็น cron อย่างพิถีพิถัน
  8. บ๊อบเป็นลุงของคุณ

ปวดหัวน้อยกว่าการสร้างและเฝ้าดูภูต

* ถ้าคุณใช้ PHP ให้จำ clearstatcache ()

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