Como manter o cron de carimbar?

13

Digamos que eu tenha vários scripts cron que precisam ser executados a cada 15 minutos. Eu poderia configurá-los para executar:, */15 * * * *mas todos eles correm ao mesmo tempo. Parece bobagem o servidor ficar ocioso por vários minutos e, de repente, tentar executar uma dúzia de scripts, tudo ao mesmo tempo.

Existe uma maneira de executar um script no minuto 1, 16, 31, 46 e outro no 2, 17, 32, 47?

Em outras palavras, quero que cada script seja executado a cada 15 minutos, mas não me importo que eles sejam executados especificamente nas marcas de quarto de hora.

Botões840
fonte

Respostas:

7

Você está tornando isso mais difícil do que precisa ser. Coloque todos na mesma linha, separados por ponto e vírgula:

*/15 * * * * command1 ; command 2 ; command 3

Ele será executado command1, espere o término, depois execute command2, espere o término e assim por diante.

laebshade
fonte
15

Se você fizer com que o seu trabalho cron fique assim: 6-59/15 * * * *será executado 6, 21, 36 e 51 minutos após a hora.

Isso pode não funcionar com todas as versões do cron.

Ladadadada
fonte
14

Você pode colocar todos os scripts em um diretório, digamos /etc/cron.15m, e depois executar o cron

*/15 * * * * run-parts /etc/cron.15m

Supondo que você tenha o run-partscomando. Está presente em todos os sistemas baseados no Debian, pelo menos. Ele executa todos os programas executáveis ​​no diretório nomeado, um de cada vez em ordem de lista.

Uma desvantagem desse método é que, se um dos scripts travar, todo o resto aguardará e não será executado. Se o tempo de execução de todos eles for superior a 15 minutos, o trabalho começará a ser executado novamente e você poderá acumular muitos processos.

Andrew Schulman
fonte
run-partstambém está presente nos sistemas Fedora / Red Hat.
mattdm
9

A maneira mais direta de fazer isso é apenas configurar manualmente os comandos para serem executados quando você desejar:

0,15,30,45 * * * * command0
1,16,31,46 * * * * command1
2,17,32,47 * * * * command2
...
14,29,44,59 * * * * command14

Ou você pode escrever um script para gerar automaticamente as entradas apropriadas do crontab (que evitam erros de digitação).

Algumas versões do cron (provavelmente a que você está usando) aceitam uma sintaxe estendida:

0-59/15 * * * * command0
1-59/15 * * * * command1
1-59/15 * * * * command2
...
14-59/15 * * * * command14
Keith Thompson
fonte
0

Cron não é realmente bom no que você está tentando fazer. Você já pensou em escrever um script que atua como um daemon que basicamente dorme 15 minutos, executa o comando e depois faz um loop?

Matt Simmons
fonte
1
Existem alguns problemas em potencial com isso. Uma é que, se você fizer sleep 300entre cada execução do comando, a própria execução do comando fará com que o tempo se desvie; pode ser executado a cada 15:10 e não a cada 15:00. E se o processo em segundo plano morrer ou o sistema reiniciar, ao contrário crond, ele não será reiniciado automaticamente. Existem maneiras de "daemonizar" um processo em segundo plano, mas você está praticamente reimplementando crond.
9788 Keith Thompson #
Sim, concordo que não é uma solução perfeita (embora você sempre possa colocar a tarefa em segundo plano com &), mas lá está.
Matt Simmons
1
Em vez disso, basta fazer com que o cron execute um único script que execute todos os seus comandos por vez. De fato, é uma necessidade tão comum que exista um script padrão chamado run-partsque seja fornecido com a maioria das instalações cron para fazer isso especificamente. Veja a resposta de @ AndrewSchulman.
tylerl
0

Muitas distribuições têm o /etc/cron.d/cronhourly, para o qual todos os scripts são executados a cada hora. Você pode até especificar a ordem iniciando-os com números seqüenciais, como 01scriptA 02scriptB - deve ser trivial com o conhecimento de cron que você já tem que fabricar um "cronhourlybyfour" como o chamamos na base de distribuição linux do Smoothwall :)

Palavra de aviso: usa peças de execução como sugerido anteriormente, e as peças de execução NÃO gostam de scripts com a. no nome, então não chame "deletehomefolders.sh" chame "01deletehomefolders" e certifique-se de começar com o # certo! linha para o que você pretende interpretar seu script.

Tom Newton
fonte