31 implica necessariamente o final do mês em um trabalho cron?

13

Para o trabalho cron, sabemos que podemos definir o tempo como abaixo.

# +------------ Minute (0 - 59)
# | +---------- Hour (0 - 23)
# | | +-------- Day of the Month (1 - 31)
# | | | +------ Month (1 - 12)
# | | | | +---- Day of the Week (0 - 7) (Sunday is 0 or 7)
# | | | | |
# * * * * * command

O que eu quero saber é que, quando definimos o dia do mês 31, isso significa o final de cada mês, embora o mês não tenha o dia 31. Espero obter resposta.

desde já, obrigado

squillman
fonte

Respostas:

22

Não, 31 significa 31.

No entanto, você pode fazer alguns truques. Defina o trabalho para ser executado em qualquer dia que possa ser o último dia do mês (por exemplo, 28-31 no campo dia do mês) e substitua seu comando por uma expressão de shell que inclua um teste na data que protege o comando:

0 0 28-31 * * [ "`date +%m`" != "`date --date=tomorrow +%m`" ] && command

A expressão entre parênteses de teste apenas pergunta se o número do mês hoje é diferente do número do mês de amanhã, o que obviamente só será verdadeiro no último dia do mês. Observe que a forma dessa expressão depende do seu local date- você pode precisar ajustá-la se não tiver a versão atual do GNU.

Devo dizer que não inventei isso - eu o encontrei com um Google rápido em uma postagem na lista de discussão de Matthew Jarvis. Eu imaginaria que esse é um truque comum do antigo assistente do Unix, no entanto.

Tom Anderson
fonte
1
Não pode ser muito velho de um truque dadas as opções específicas do GNU para "data" =)
jj33
4
Nos sites stackexchange, fazer uma pergunta que possa ser respondida com uma pesquisa no Google, NÃO é uma coisa ruim. Na verdade, é uma coisa boa, pois a próxima pessoa que pesquisar isso no Google encontrará a resposta no stackexchange e virá aqui.
miernik
12

Não, acho que o melhor que você pode fazer é executar à meia-noite do primeiro dia do mês ou configurar linhas de crontab individuais para cada mês (ou pelo menos uma linha para meses com 28,29,30 e 31 dias)

0 0 28,29 2               * /my/command
0 0 30    4,6,9,11        * /my/command
0 0 31    1,3,5,7,8,10,12 * /my/command
Paul Dixon
fonte
Obrigado Paul! Eu seguirei o segundo. Para o segundo método, preciso definir o mesmo arquivo por três vezes, certo? Obrigado novamente :)
Sim, você precisará repeti-lo.
217 Paul Dixon
7
Não tenho experiência com cron, mas "0 0 28,29 2" não seria executado duas vezes em um ano bissexto? Não que isso seria um problema para os próximos dois anos, mas ainda assim ...
Wim ten Brink
Esse é um ponto bom, nenhuma maneira fácil em torno disso
Paul Dixon
4

Eu não acho que você pode fazer isso facilmente no crontab.

Uma opção seria definir crona execução do script todos os dias e fazer com que o próprio script verifique se é o último dia do mês.

Dave Webb
fonte
3

Eu acho que o cron tem um caractere especial 'L' para esse fim:

*    *    L    *    *    your_script.sh 

executaria seu script no último dia de cada mês

Por outro lado,

*    *    0    *    *    your_script.sh

Você pode até especificar algo como:

*    *    *    *    1,5L    your_scrript.sh

para executar o script na última segunda e sexta-feira de cada mês

ou

*    *    *    *    1    your_script.sh

para executar o script toda segunda-feira à meia-noite.

Saasira
fonte
0

Isso fará o trabalho:

if [ $( date +%-d --date="tomorrow" ) -eq 1 ]
then echo Last day of the current month
else echo Not yet!
     exit 0
fi

exit 1
Phil
fonte