Her gün 1 saat sonra bir cronjob'a nasıl başlayabilirim?


16

Her gün bir cronjob başlatmam gerekiyor, ama her gün bir saat sonra. Şimdiye kadar sahip olduğum şey yılın 1 günü hariç çoğunlukla çalışıyor:

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

Yılın günü 365 olduğunda, iş 5: 00'da başlayacaktır, ancak ertesi gün (artık yıl sayılmaz) yılın 1 günü olacaktır, bu yüzden iş 1: 00'da başlayacaktır. Bu köşe kutusundan nasıl kurtulabilirim?


1
Sadece 25 saatte bir başlamamak için bir sebep var mı?
HalosGhost

7
Ve bunu tam olarak nasıl yapardın? * / 25 saat pozisyonunda çözmez.
huş ağacı

@HalosGhost Öneriniz için teşekkürler! Adresinde basit bir uygulama yazdım.
Giulio Muscarello

Yanıtlar:


23

Benim tercih ettiğim çözüm, her saat başı işe başlamak ama betiğin çalışma zamanının olup olmadığını kontrol etmesini ve 25'ten 24 kez hiçbir şey yapmadan çıkmasını sağlamaktı.

crontab:

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

üst kısmında myprog:

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

Komut dosyasının kendisinde herhangi bir değişiklik yapmak istemiyorsanız, crontab girdisine "çalıştırma zamanı" onayını da koyabilirsiniz, ancak uzun ve çirkin bir satır oluşturur:

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

1
'%' ın crontab'da ters eğik çizgi ile kaçması gerekiyor.
huş ağacı

@birch Bunu hiç bilmiyordum! Sanırım daha önce bir crontab'a% eklemeyi denemedim. Düzeltme için teşekkürler, cevabı düzenledim.
Celada

1
Bu bana iyi geliyor. OP'nin Gün Işığından Yararlanma Saati ile ilgili ne yapmak istediğine dair hiçbir fikrim yok (bahar ilerleyin, geride kalın), ancak OP buna göre ayarlamalar yapmalıdır.
emory

Bölümün yuvarlanması konusunda biraz endişeliydim. Herhangi bir nedenle dateçekirdekten geri dönen 1mszaman, komut dosyasının çalışmasını beklediğiniz zamandan önce olsaydı, denetim yanlış bir sonuç verirdi.
kasperd

1
@kasperd Bilmiyorum, sanırım farklı zaman bildiren farklı CPU'lar hakkında haklı olabilirsiniz. Gelince ntpd, sadece bu tür bir problemden kaçınmak için sadece saati döndürmek, atlamak değil, ama haklısınız, ntpdatebazen (veya ) bazen geriye doğru atlayabilir. cronUyku gecikmesini yanlış hesaplamaya gelince, bunun bir hata olarak kabul edileceğinden eminim! Yine de, nokta alınır ve bir çözüm, soruna neden olma olasılığı daha düşük olan işi saatten 30 dakika sonra planlamak olacaktır ... Veya 3600 reamainder modunu almadan önce aritmetik ifadeye ± 1800 ekleyin.
Celada

7

Sisteminizde systemd varsa, bunun için zamanlayıcı olaylarını kullanabilirsiniz. Sadece yürütmek istediğiniz komutu / görevi içermesi gereken yeni bir hizmet tanımlayın ve ardından OnUnitActiveSecseçenekle birlikte bir timer olayı oluşturun :

[Unit]
Description=daily + 1 hour task

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

[Install]
WantedBy=timers.target

Dosyalar yerine aynı adı kullanın, bunun yerine .servicekullanmak yerine .timer.

Sentezleme:

  1. Adlı bir dosya oluşturun job.serviceiçinde /etc/systemd/system/dizine.
  2. Gerekli bilgilerle doldurun. Tuşlarını kullanarak yapılandırmayı doğrulayabilirsiniz systemctl status job.service.
  3. Adlı bir dosya oluşturun job.timeriçinde /etc/systemd/system/.
  4. Gerekli bilgilerle doldurun:

    [Unit]
    Description=daily + 1 hour task
    
    [Timer]
    OnUnitActiveSec=25h # run 25 hours after service was last started
    AccuracySec=10min
    
    [Install]
    WantedBy=timers.target
    
  5. Zamanlayıcıyı kullanarak doğrulayın. systemctl list-timers
  6. Bitti.

Eğer cron basitliğinden uzaklaşacak olsaydım, systemd örneğinizden daha az iş gerektirecek olan launchd kullanırdım.
huş

6

Eğer cronjobs dışında bir şey kullanmak sakıncası yoksa, daha az bilinen yardımcı programı öneririm at. Hem kendisini 25 saat içinde çalışacak şekilde zamanlayan, hem de programınızı çağıran bir sarıcı komut dosyası yazmanız yeterlidir. Bu en temiz çözüm gibi görünüyor.
Örneğin, bunu ~ / script.sh dosyasına yazabilirsiniz:

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

Ve sonra sadece bir bash ~/script.shkez koş .

İşi 25 saatte bir zamanlama fikri için @HalosGhost'a teşekkürler.


2
atBu amaçla kullanımla ilgili 2 sorun vardır : (1) iş bir kez bile doğru bir şekilde yürütülemezse, muhtemelen bir sonraki yürütmeyi değil, aynı zamanda kendisini yeniden planlayamaz, ancak gelecekteki tüm yürütmeler bir insan farkına kadar etkili bir şekilde iptal edilir ve (2) işin çalışması sıfırdan fazla zaman aldığından, saf olanı kullanarak now + 25 hoursher seferinde birkaç saniye (veya daha fazla) çalışacağı anlamına gelirse, bu gecikme zamanla birikir ve sonunda tamamen yanlış çalışır saati.
Celada

2
# 1 hakkında haklısın; # 2 konusunda pek emin değilim. Herhangi bir veri olmamasına rağmen, saat değişimi ile tetiklenen iş arasındaki gecikmenin ve daha sonra yeniden planlananın arasındaki gecikmenin farkedilebilecek kadar büyük olduğunu düşünmüyorum - özellikle çözünürlüğünün atdakikalarla sınırlı olduğunu ve tüm işleri başlattığını göz önünde bulundurarak [zamanda]: 00.
Giulio Muscarello

1
@Celada: At betiğindeki ilkat işin zamanlanması bu sorunları önler. Rağmen, eğer bir hata oluşursa sonra tüm zincir veya arzu olabilir veya olmayabilir, hangi bozuldu: kullanım durumu ise, değil yeniden başlatmadan büyük özelliktir "çalıştığını yalnızca bu çalıştırın". Ancak kullanım durumu "her zaman çalışır, son başarısız olsa bile" o zaman doğru araç değildir. at
Piskopos
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.