Como programar o cronjob a cada 45 dias?

2

Como executar um script de shell através de um cronjob a cada 45 dias?

    
por PRAKASH 09.05.2018 / 16:36

4 respostas

2

Se você não precisa exatamente de 45 dias, mas sim de "um mês e meio", um método simples seria a execução no início do mês a cada três meses e no meio do próximo mês. depois de cada um deles:

0 12  1 1,4,7,10  * /path/to/script
0 12 16 2,5,8,11  * /path/to/script

Para intervalos gerais arbitrários, as outras respostas são obviamente melhores, mas de qualquer forma, 45 dias parece ter sido baseado na duração de um mês. Os usuários humanos também podem estar mais acostumados a algo acontecendo no começo ou no meio de um mês, em vez de ver a data exata derivar um dia ou dois de cada vez.

    
por 09.05.2018 / 22:17
5

Como o cron não suporta uma tradução simples e direta desse requisito, eu o abordaria com um arquivo de registro de data e hora e um trabalho cron diário:

0 0 * * * /path/to/wrapper/script/below.sh

o script do wrapper:

#!/bin/bash
timestampfile=/var/run/this-job/timetampfile

# exit now if it hasn't been 45 days
(( 
  $(date +%s) - $(stat -c %Z "$timestampfile") 
            < 
  (45 * 24 * 60 * 60) 
)) && exit 0

touch "$timestampfile"
: run real script here

Isso gera vários riscos:

  • alguém excluindo o arquivo de carimbo de data / hora
  • alguém tocando no arquivo de timestamp (para melhor ou para pior)
  • deixando não óbvio a partir da entrada da tarefa cron que o script real é executado a cada 45 dias
por 09.05.2018 / 17:09
4

Com base em esta resposta no estouro de pilha , você poderia fazer isso com a seguinte sintaxe:

00 12 * * *  test $(( $(date +\%s)/24/60/60\%45 )) = 20 && your_script

Este trabalho será executado todos os dias ao meio-dia. Em seguida, calcula o módulo do número de dias da época e testa se é igual ao módulo que você especificar. Neste caso, eu especifiquei 20, o que o tornaria verdadeiro para hoje (2018-05-09 entre 00:00 GMT e 23:59 GMT), então 45 dias a partir de hoje, etc. Você pode calcular / testar com o seguinte:

$ echo $(( $(date +%s)/24/60/60%45 ))
20
$ echo $(( $(date -d '+45 days' +%s)/24/60/60%45 ))
20
$ echo $(( $(date -d '+44 days' +%s)/24/60/60%45 ))
19

(lembre-se de que, se você não estiver em um fuso horário UTC, talvez seja necessário considerar a hora do dia).

    
por 09.05.2018 / 16:50
2

Solução alternativa: systemd está comendo todas as partes do sistema Linux. Com isso em mente, agora ele tem uma unidade timer que pode ser relacionada a uma unidade service de mesmo nome para criar uma programação e imitar anacron. Exemplo:

Serviço. Chamaremos de foo e o script /home/user/foo.sh será executado. Ao trabalhar com temporizadores, sua unidade service não precisa ter a seção [Install] :

/etc/systemd/system/foo.service

[Unit]
Description=My foo script

[Service]
Type=simple
ExecStart=/home/user/foo.sh

Temporizador. Esta é a unidade especial que irá lidar com o horário:

/etc/systemd/system/foo.timer

[Unit]
Description=Run foo every 45 days and on boot
Persistent=true

[Timer]
OnBootSec=15min
OnUnitActiveSec=45d 

[Install]
WantedBy=multi-user.target

Observando a seção [Timer] , seu script será executado 15 minutos após a inicialização (você pode remover isso) e a cada 45 dias. O parâmetro Persistent= significa que, mesmo após a reinicialização, a programação persistirá no disco e não será reiniciada.

E, em seguida, ative as duas unidades:

systemctl enable foo.service
systemctl enable foo.timer

Você pode não gostar de systemd , mas essa é uma solução rápida para problemas com agendamento e cron .

Leitura adicional:

por 09.05.2018 / 22:59

Tags