É possível executar um cronjob a cada três dias? Ou talvez 10 vezes / mês.
É possível executar um cronjob a cada três dias? Ou talvez 10 vezes / mês.
Respostas:
Execute-o a cada três dias ...
0 0 */3 * *
Que tal isso?
Se você quiser que ele seja executado em dias específicos do mês, como 1º, 4º, 7º, etc ... então você pode apenas ter uma condicional em seu script que verifica o dia atual do mês.
if (((date('j') - 1) % 3))
exit();
ou, como @mario aponta, você pode usar a data ('k') para obter o dia do ano em vez de fazer isso com base no dia do mês.
0 0 */3 * *
significa execução no dia 1, 4, 7, etc. ( */3
significa 1-31/3
significa 1,4,7...31
), de modo que o intervalo será menor no final do mês. (Ele será executado 2 dias consecutivos se o mês anterior tiver 31 dias.) O date('j') % 3
tem um problema semelhante, pois o padrão é reiniciado a cada ano e os anos não têm um número de dias divisível por 3.
* * */3 * * that says, every minute of every hour on every three days.
0 0 */3 * * says at 00:00 (midnight) every three days.
Não sou um especialista em cron, mas que tal:
0 */72 * * *
Ele será executado a cada 72 horas ininterruptas.
then at 2019-02-28 00:00:00 then at 2019-03-01 00:00:00
Como o cron é "sem estado", ele não pode expressar com precisão "frequências", apenas "padrões" que (aparentemente) compara continuamente com a hora atual.
Reformular sua pergunta torna isso mais óbvio: "é possível executar um cronjob às 00:01 todas as noites, exceto pular noites quando ele era executado em 2 noites?" Quando o cron está comparando a hora atual com os padrões de tempo de solicitação de trabalho, não há como o cron saber se executou seu trabalho no passado.
Normalmente, você precisa encerrar aquele evento recorrente e reiniciar um completamente novo; isso ilustra a expressividade limitada de como até mesmo aplicativos de calendário complicados representam padrões repetidos. E, claro, os calendários têm muitos estados - cada evento individual pode ser excluído ou reprogramado de forma independente [na maioria dos aplicativos de calendário]).
Além disso, você provavelmente deseja fazer seu trabalho a cada 3 noites se for bem-sucedido , mas se o último falhar, tente novamente imediatamente, talvez na noite seguinte (não espere mais 3 dias) ou até mais cedo, como uma hora depois (mas pare de tentar novamente na chegada da manhã). Claramente, o cron não poderia saber se sua tarefa foi bem-sucedida e o padrão também não pode expressar uma programação de "nova tentativa" alternativa mais frequente.
DE QUALQUER MANEIRA - Você pode fazer o que quiser sozinho. Escreva um script, diga ao cron para executá-lo todas as noites às 00:01. Este script pode verificar o carimbo de data / hora de algo * que registra a "última execução" e, se for> 3 dias atrás **, execute o trabalho e redefina o carimbo de data / hora da "última execução".
(* aquele indicador com carimbo de data / hora é um pouco de estado persistente que você pode manipular e examinar, mas que o cron não pode)
** tenha cuidado com a aritmética do tempo se estiver usando um relógio legível - duas vezes por ano, alguns dias têm 23 ou 25 horas em seu dia, e 02: 00-02: 59 ocorre duas vezes em um dia ou não em tudo. Use UTC para evitar isso.
0 0 1-30/3 * *
Isso seria executado a cada três dias, começando em primeiro. Aqui estão as 20 execuções programadas -
Não acho que você tenha o que precisa com:
0 0 */3 * * ## <<< WARNING!!! CAUSES UNEVEN INTERVALS AT END OF MONTH!!
Infelizmente, o * / 3 está definindo o intervalo a cada n dias do mês e não a cada n dias . Veja: explicação aqui . No final do mês há emissão recorrente garantida.
1st at 2019-02-01 00:00:00
then at 2019-02-04 00:00:00 << 3 days, etc. OK
then at 2019-02-07 00:00:00
...
then at 2019-02-25 00:00:00
then at 2019-01-28 00:00:00
then at 2019-03-01 00:00:00 << 1 day WRONG
then at 2019-03-04 00:00:00
...
De acordo com este artigo , você precisa adicionar alguns módulos matemáticos ao comando que está sendo executado para obter um TRUE "a cada N dias". Por exemplo:
0 0 * * * bash -c '(( $(date +\%s) / 86400 \% 3 == 0 )) && runmyjob.sh
Neste exemplo, o trabalho será verificado diariamente às 12h00, mas só será executado quando o número de dias desde 01-01-1970 módulo 3 for 0.
Se você quiser que seja a cada 3 dias a partir de uma data específica, use o seguinte formato:
0 0 * * * bash -c '(( $(date +\%s -d "2019-01-01") / 86400 \% 3 == 0 )) && runmyjob.sh
E se:
00 00 * * * every 3 days && echo test
Onde every
está um script:
#!/bin/sh
case $2 in
days)
expr `date +%j` % $1 = 0 > /dev/null
;;
weeks)
expr `date +%V` % $1 = 0 > /dev/null
;;
months)
expr `date +%m` % $1 = 0 > /dev/null
;;
esac
Por isso, funciona todos os dias.
Usar */3
é executado nos dias 3, 6, ... 27, 30 do mês, mas está errado depois de um mês ter um 31 dia. O every
roteiro só fica errado depois do final do ano.
Você deve aprender o básico de crontab
.
Edite o cron pelo comando crontab -e
e, em seguida, ⌃ (CTRL)+ Xentão Ye, finalmente imprensa ENTER (return)no Mac para salvar o arquivo. Você pode verificar se os novos crons foram instalados ou não porcrontab -l
Um arquivo crontab tem cinco campos para especificar minutos, horas, o dia do mês, mês e dia da semana, seguido pelo comando a ser executado naquele intervalo.
* * * * * command to be executed
- - - - -
| | | | |
| | | | +----- day of week (0-6) (Sunday=0)
| | | +------- month (1-12)
| | +--------- day of month (1-31)
| +----------- hour (0-23)
+------------- min (0-59)
*
no campo de valor acima significa todos os valores legais como entre chaves para essa coluna.
Aqui, escrevi um post detalhado sobre isso: Setup Cron no Unix
Seria mais simples se você configurasse apenas para rodar, por exemplo, às segundas e quintas-feiras, o que lhe daria um intervalo de 3 e 4 dias.
Caso contrário, configure-o para ser executado diariamente, mas faça com que o script cron php saia mais cedo com:
if (! (date("z") % 3)) {
exit;
}
Se você quiser que ele seja executado em dias específicos do mês, como 1º, 4º, 7º, etc ... então você pode apenas ter uma condicional em seu script que verifica o dia atual do mês.
Achei que tudo que você precisava para isso era em vez de * / 3, o que significa a cada três dias, use 1/3, o que significa a cada três dias a partir do primeiro dia do mês. então 7/3 significaria a cada três dias, começando no dia 7 do mês, etc.
0 0 * * * [ $(($((
data +% - j- 1)) % 3)) == 0 ] && script
Obtenha o dia do ano a partir de date
, compensado por 1 para começar em 0, verifique se é o módulo três.
( 365-1 ) % 3 == 1
mas ( 1 - 1 ) % 3 == 0
? Eu acho que o melhor cálculo seria baseado no número de dias desde a época do Unix.