Como posso iniciar um cronjob 1 hora depois a cada dia?

16

Eu preciso começar um cronjob todos os dias, mas uma hora depois a cada dia. O que eu tenho até agora funciona na maior parte, com exceção de 1 dia do ano:

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

Quando o dia do ano for 365, o trabalho começará às 5:00, mas no dia seguinte (sem contar um ano bissexto) terá um dia do ano como 1, portanto o trabalho começará às 1:00. Como posso me livrar deste caso de esquina?

    
por birch 10.08.2014 / 04:40

3 respostas

23

Minha solução preferida seria iniciar o trabalho a cada hora, mas ter o script em si para verificar se é hora de executar ou não e sair sem fazer nada 24 vezes em 25.

crontab:

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

na parte superior de myprog :

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

Se você não quiser fazer alterações no próprio script, você também pode colocar a opção "time to run" na entrada do crontab, mas isso cria uma linha longa e desagradável:

0 * * * *    [ 0 -eq $(( $(date +\%s) / 3600 \% 25 )) ] && /usr/local/bin/myprog
    
por 10.08.2014 / 05:42
7

Se o seu sistema tiver o systemd, você poderá usar eventos de temporizadores para isso. Basta definir um novo serviço , que deve conter o comando / tarefa que você deseja executar e, em seguida, crie um evento de timer com a opção OnUnitActiveSec :

[Unit]
Description=daily + 1 hour task

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

[Install]
WantedBy=timers.target

Use o mesmo nome para os arquivos, exceto que, em vez de .service , você usa .timer .

Sintetizando:

  1. Crie um arquivo chamado job.service no diretório /etc/systemd/system/ .
  2. Preencha com as informações necessárias. Você pode verificar a configuração, usando systemctl status job.service .
  3. Crie um arquivo chamado job.timer in /etc/systemd/system/ .
  4. Preencha com as informações necessárias:

    [Unit]
    Description=daily + 1 hour task
    
    [Timer]
    OnUnitActiveSec=25h # run 25 hours after service was last started
    AccuracySec=10min
    
    [Install]
    WantedBy=timers.target
    
  5. Verifique o cronômetro usando systemctl list-timers
  6. Feito.
por 10.08.2014 / 20:27
6

Se você não se importar em usar algo diferente de cronjobs, sugiro o utilitário menos conhecido at . Basta escrever um script wrapper que seja programado para ser executado em 25 horas e, em seguida, chamar seu programa. Esta parece ser a solução mais limpa.
Por exemplo, você poderia escrever isso em ~ / script.sh:

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

E, em seguida, basta executar bash ~/script.sh uma vez.

Obrigado ao @HalosGhost pela idéia de agendar o trabalho uma vez em 25 horas.

    
por 10.08.2014 / 15:13

Tags