Cron empregos e tempos randoms, dentro de determinadas horas

Eu preciso da habilidade de executar um script PHP 20 vezes por dia em tempos completamente randoms. Eu também quero que ele seja executado apenas entre 9:00 – 23:00.

Estou familiarizado com a criação de tarefas agendadas no linux.

Se eu entendi o que você está procurando, você precisa fazer algo um pouco confuso, como ter um cron job que executa um script bash que randomiza os tempos de execução … Algo parecido com isto:

crontab:

0 9 * * * /path/to/bashscript 

e em / path / to / bashscript:

 #!/bin/bash maxdelay=$((14*60)) # 14 hours from 9am to 11pm, converted to minutes for ((i=1; i<=20; i++)); do delay=$(($RANDOM%maxdelay)) # pick an independent random delay for each of the 20 runs (sleep $((delay*60)); /path/to/phpscript.php) & # background a subshell to wait, then run the php script done 

Algumas notas: essa abordagem é um pouco de desperdício de resources, pois triggers 20 processos em segundo plano às 9h, cada um aguarda um número random de minutos (até 14 horas, ou seja, 11h), depois lança o script php e sai. Além disso, como usa um número random de minutos (não segundos), os horários de início não são tão randoms quanto poderiam ser. Mas o $ RANDOM só sobe para 32.767, e há 50.400 segundos entre 9:00 e 23:00, seria um pouco mais complicado randomizar os segundos também. Finalmente, como os tempos de início são randoms e independentes um do outro, é possível (mas não muito provável) que duas ou mais instâncias do script sejam iniciadas simultaneamente.

Sim, sim, a questão tem mais de um ano, mas talvez eu possa acrescentar algo útil:

Como cron algo em um deslocamento random 20 vezes por dia, entre 9 e 23? Isso é meio complicado no cron, porque você está dividindo 14 horas em 20 tempos de execução. Eu não gosto muito das outras respostas porque elas exigem que você escreva um script de wrapper bash para o seu script php.

No entanto, se você me permitir a liberdade de diminuir a restrição de tempo e frequência para 13 vezes entre 8:30 e 23:09, isso poderá resolver o problema, e tudo dentro dos limites do seu crontab:

 30 8-21/* * * * sleep ${RANDOM:0:2}m ; /path/to/script.php 

$ {RANDOM: 3: 2} usa o $ RANDOM do bash que outras pessoas mencionaram acima, mas adiciona o fatiamento do array bash. Como as variables ​​bash não são tipificadas, o número de 16 bits assinado pseudo-random é truncado para o primeiro 2 de seus 5 dígitos decimais, dando a você um one-liner sucinto para atrasar seu cronjob entre 10 e 99 minutos (embora a distribuição seja direcionada para 10 a 32).

O seguinte também pode funcionar para você, mas eu achei que seria “menos random” por algum motivo (talvez a Lei de Benford seja acionada pela modulação de números pseudo-randoms. Ei, eu não sei, eu fui reprovado em matemática …) no bash!):

 30 8-21/* * * * sleep $[RANDOM\%90]m ; /path/to/script.php 

Você precisa renderizar o módulo como ‘\%’ acima porque o cron (bem, pelo menos Linux ‘vixie-cron’) finaliza a linha quando encontra um ‘%’ sem escape.

Talvez você possa obter as 7 execuções de scripts restantes adicionando outra linha com outro intervalo de 7 horas. Ou relaxe sua restrição para correr entre 3h e 23h.

Então, estou usando o seguinte para executar um comando entre 1AM e 330AM

 0 1 * * * perl -le 'sleep rand 9000' && *command goes here* 

Isso tem tomado conta das minhas necessidades aleatórias para mim. São 9000 segundos == 150 minutos == 2,5 horas

Cron oferece uma variável RANDOM_DELAY . Veja crontab(5) para detalhes.

A variável RANDOM_DELAY permite atrasar a boot de trabalhos por quantidade aleatória de minutos com o limite superior especificado pela variável.

Isso é visto comumente em tarefas do anacron , mas também pode ser útil em um crontab .

Pode ser necessário ter cuidado com isso se você tiver alguns trabalhos que são executados com granularidade fina (de minutos) e outros que são grosseiros.

Meu primeiro pensamento seria criar um cron job que fosse lançado 20 vezes aleatoriamente em jobs. O utilitário at (http://unixhelp.ed.ac.uk/CGI/man-cgi?at) é usado para executar comandos no tempo especificado.

Acabei usando o sleep $(( 1$(date +%N) % 60 )) ; dostuffs sleep $(( 1$(date +%N) % 60 )) ; dostuffs (compatível com bash & sh)

O prefixo 1 é para forçar a interpretação da base NON 8 da data +% N (por exemplo, 00551454)

Não esqueça de escaping% usando \% em um arquivo crontab

* * * * * nobody sleep $(( 1$(date +\%N) \% 60 )) ; dostuffs

at -f [file] [timespec]

ou

echo [command] | at [timespec]

ou

at [timespec] … e especificação interativa como gravação de script .

Comando

Em executa o texto fornece em stdin ou no arquivo especificado por -f [file] .

Timespec

Aqui está a gramática [timespec] . Pode ser algo como:

  • 24 horas como int de 4 dígitos, por exemplo, 0100 , 2359 , 1620
  • now + 10 minutes
  • 2071-05-31 - 5 hours 12 minutes UTC

Se você especificar explicitamente o fuso horário, algumas versões do timespec só poderão permitir o UTC para o argumento de fuso horário opcional.

Exemplo

cat script.sh | at now + $(($RANDOM % 10)) hours $(($RANDOM % 60)) minutes

at -f script.sh now + $(($RANDOM % 10)) hours $(($RANDOM % 60)) minutes

Experimente…

Você pode testar o bash parsing por echo pré-pendente e escaping | (tubo).

echo cat script.sh \| at now + $(($RANDOM % 10)) hours $(($RANDOM % 60)) minutes

echo at -f script.sh now + $(($RANDOM % 10)) hours $(($RANDOM % 60)) minutes

Para ver as tarefas agendadas, use o conteúdo de atq e job (ambiente vars, setup e command / script) com at -c [jobid] .

Nota

O sistema faz parte do cron e, na verdade, o prompt interativo captura todo o estado atual do seu shell, para que você possa executar comandos sem especificar caminhos absolutos.

Para aqueles que procuraram o caminho aqui:

Se você estiver usando anacron (Ubuntu desktop e laptop), então você pode editar

 /etc/anacrontab 

e adicione

 RANDOM_DELAY=XX 

Onde XX é a quantidade de minutos que você deseja atrasar o trabalho base.

O Anacron é como o cron, mas não espera que o seu computador esteja em 24×7 (como nossos laptops) e executará os scripts perdidos porque o sistema estava inativo.