Como posso dizer ao cron para executar um comando todos os dias (ímpar / par)?

37

Ao configurar o cron para executar um comando a cada dois dias usando o campo "Dia do mês", assim:

1 22 */2 * * COMMAND

ele é executado toda vez que o dia do mês é ímpar: 1,3,5,7,9 e assim por diante.

Como posso configurar o cron para ser executado em dias do mês que são parecidos com 2,6,8,10 e assim por diante (sem especificá-lo literalmente, o que é problemático, pois todo mês tem um número diferente de dias no mês) ?

    
por freddie 05.07.2011 / 14:47

4 respostas

53

A sintaxe que você tentou é realmente ambígua. Dependendo de quantos dias são no mês, alguns meses serão executados em dias ímpares e alguns em dias pares. Isso ocorre porque a maneira como é calculada leva o número total de posibilidades e as divide. Você pode ignorar esse comportamento distorcido especificando manualmente o intervalo de dias e usando um número ímpar ou par de dias. Como os scripts de um dia sequer seriam executados no 31º dia de meses mais longos, você não perde nada usando 30 dias como base para dias pares e, especificando especificamente para dividi-lo como se houvesse 31 dias, você pode forçar um número ímpar. execução de dia.

A sintaxe ficaria assim:

# Will only run on odd days:
0 0 1-31/2 * * command

# Will only run on even days:
0 0 2-30/2 * * command

Sua preocupação com meses não tendo o mesmo número de dias não é importante aqui porque nenhum mês tem MAIS dias além disso e para fevereiro ruim, o intervalo de datas não irá corresponder ao último dia ou dois, mas fará nenhum dano ter listado.

A única 'pegadinha' para essa abordagem é que, se você estiver em um ciclo de dias ímpares, seguindo meses com 31 dias, seu comando também será executado no primeiro dia do mês. Da mesma forma, se você está forçando um ciclo par, cada ano bissexto causará um ciclo de três dias e o final de fevereiro. Você não pode realmente contornar o fato de que qualquer padrão regular de "todos os dias" nem sempre vai cair em dias pares ou ímpares em todos os meses e de qualquer forma que você forçar isso, você terá uma corrida extra ou perderá uma corrida entre meses com contagens de dias sem correspondência.

    
por 05.07.2011 / 14:54
2

Eu acho que uma possibilidade é usar o dia do ano, como:

# for odd days
test $((('date +%j' % 2))) != 0 && command

# for even days
test $((('date +%j' % 2))) == 0 && command

Ele é testado para sistemas Unix e Linux.

    
por 13.01.2015 / 08:13
1

Vamos verificar todos os dias se é um "outro" :-) ( bc programa exigido)

0 0 * * * test $(echo 'date +%s' / 86400 % 2 == 0 |bc) -eq 0 && command

(Não tenho certeza se o código aparece corretamente. A parte date +%s está entre os apóstrofos anteriores.)

    
por 16.04.2013 / 12:23
1

Em geral, eu o executaria todos os dias e teria o script usando a lógica para determinar se deveria ser executado hoje.

Fazer um arquivo de status simples informando quando a última execução e a compairing funcionaria com muita facilidade.

Se precisar ser executado por diferentes fontes, torne-o dependente de argumentos.

    
por 01.09.2017 / 13:04

Tags