Preciso executar um script PHP 20 vezes por dia em horários completamente aleatórios. Eu também quero que ele funcione apenas entre 9h e 23h.
Estou familiarizado com a criação de tarefas cron no Linux.
Preciso executar um script PHP 20 vezes por dia em horários completamente aleatórios. Eu também quero que ele funcione apenas entre 9h e 23h.
Estou familiarizado com a criação de tarefas cron no Linux.
Respostas:
Se eu entendi o que você está procurando, você precisará fazer algo um pouco confuso, como ter um cron job que executa um script bash que randomiza os tempos de execução ... Algo assim:
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: esta abordagem é um pouco desperdiçadora de recursos, pois dispara 20 processos em segundo plano às 9h, cada um dos quais espera por um número aleatório de minutos (até 14 horas, ou seja, 23h), em seguida, inicia o script php e saídas. Além disso, como ele usa um número aleatório de minutos (não segundos), os horários de início não são tão aleatórios quanto poderiam ser. Mas $ RANDOM só sobe para 32.767, e há 50.400 segundos entre 9h e 23h, seria um pouco mais complicado randomizar os segundos também. Finalmente, como os horários de início são aleatórios e independentes um do outro, é possível (mas não muito provável) que duas ou mais instâncias do script sejam iniciadas simultaneamente.
((maxdelay = 14 * 60))
ou ((delay = $RANDOM % maxdelay))
). O sleep
argumento ainda precisa ser do jeito que você tem (embora você possa adicionar espaços, se desejar).
sleep $[ ( $RANDOM % 60 ) + 1 ]s && some_script.sh
Sim, sim, a pergunta tem mais de um ano, mas talvez eu possa acrescentar algo útil:
Como cron algo em um deslocamento aleatório 20 vezes por dia entre 9h e 23h? Isso é meio complicado no cron, porque você divide 14 horas por 20 tempos de execução. Eu não gosto muito das outras respostas porque elas requerem a escrita de um script bash wrapper para 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 8h30 e 23h09, isso pode 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 do bash. Como as variáveis bash não são digitadas, o número pseudoaleatório de 16 bits com sinal fica truncado para os primeiros 2 de seus 5 dígitos decimais, dando-lhe uma linha sucinta para atrasar seu cronjob entre 10 e 99 minutos (embora a distribuição seja tendenciosa para 10 a 32).
O seguinte também pode funcionar para você, mas eu descobri que é "menos aleatório" por algum motivo (talvez a Lei de Benford seja acionada pela modulação de números pseudo-aleatórios. Ei, eu não sei, fui reprovado em matemática ... A culpa é disso 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') termina a linha quando encontra um '%' sem escape.
Talvez você possa obter as 7 execuções de script restantes adicionando outra linha com outro intervalo de 7 horas. Ou relaxe sua restrição para correr entre 3h e 23h.
$[(RANDOM/368)+10]
?
$((RANDOM % 90 + 10))
Teste:for i in {0..9999}; do echo $((RANDOM % 90 + 10)); done | sort | uniq -c
$RANDOM
: sleep $(( $(od -N1 -tuC -An /dev/urandom) \% 90 ))m
.
crontab
está usando bash
antes de usar $RANDOM
. Se tiver vixie-cron
(parece ser o meu caso no Ubuntu), você pode adicionar SHELL=/bin/bash
ao topo. Existem mais alternativas para outras versões do cron aqui: superuser.com/a/264541/260350
crontab: errors in crontab file, can't install. Do you want to retry the same edit?
ajuda
Então, estou usando o seguinte para executar um comando entre 1h e 330h
0 1 * * * perl -le 'sleep rand 9000' && *command goes here*
Isso tem cuidado de minhas necessidades aleatórias para mim. Isso dá 9000 segundos == 150 minutos == 2,5 horas
Cron oferece um RANDOM_DELAY
variável. Veja crontab(5)
para detalhes.
A variável RANDOM_DELAY permite atrasar o início da tarefa por uma quantidade aleatória de minutos com o limite superior especificado pela variável.
Isso é visto comumente em anacron
empregos, mas também pode ser útil em a crontab
.
Você pode precisar ter cuidado com isso se tiver alguns trabalhos que são executados em granularidade fina (minuto) e outros que são grosseiros.
RANDOM_DELAY
é estabelecido uma vez e permanece constante durante todo o tempo de execução do daemon.
RANDOM_DELAY
bandeira é um recurso do cronie-crond enquanto o Ubuntu parece estar em execução, vixie-cron
mas não tem essa bandeira.
Meu primeiro pensamento seria criar um cron job lançando 20 agendados aleatoriamente em jobs. O at
utilitário (http://unixhelp.ed.ac.uk/CGI/man-cgi?at) é usado para executar comandos em um horário especificado.
Acabei usando sleep $(( 1$(date +%N) % 60 )) ; dostuffs
(compatível com bash & sh)
O prefixo 1 é para forçar a interpretação NON base 8 da data +% N (por exemplo, 00551454)
Não se esqueça de escapar% usando \% em um arquivo crontab
* * * * * nobody sleep $(( 1$(date +\%N) \% 60 )) ; dostuffs
date
(o que você provavelmente tem na maioria dos Linuxes, mas não no Busybox, MacOS padrão ou várias outras plataformas derivadas de BSD).
A solução de al-x não funciona para mim, pois os comandos crontab não são executados em bash, mas em sh, eu acho. O que funciona é:
30 8 * * * bash -c "sleep $[RANDOM\%90]m" ; /path/to/script.py
$[ ... ]
é uma sintaxe obsoleta desde waaaay de volta; para qualquer coisa deste milênio, você prefere $((RANDOM\%90))m
qual é a sintaxe compatível com POSIX (mas RANDOM
é claro que ainda é apenas Bash).
at -f [file] [timespec]
ou
echo [command] | at [timespec]
ou
at [timespec]
... e especificações interativas como script
a gravação de.
Em executa o texto fornecido em stdin ou no arquivo especificado por -f [file]
.
Aqui está a [timespec]
gramática . Pode ser algo como:
0100
, 2359
,1620
now + 10 minutes
2071-05-31 - 5 hours 12 minutes UTC
Se você estiver especificando explicitamente o fuso horário, algumas versões do timespec podem permitir apenas UTC
o argumento opcional de fuso horário.
cat script.sh | at now + $(($RANDOM % 10)) hours $(($RANDOM % 60)) minutes
at -f script.sh now + $(($RANDOM % 10)) hours $(($RANDOM % 60)) minutes
Você pode testar a análise bash fazendo uma pré-pendente echo
e escapando do |
(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 os trabalhos agendados, use atq
e o conteúdo do trabalho (variáveis de ambiente, configuração e comando / script) com at -c [jobid]
.
O sistema é parte do cron e o prompt interativo realmente captura todo o estado atual do seu shell, para que você possa executar comandos sem especificar caminhos absolutos.
Para quem pesquisou o caminho até aqui:
Se você estiver usando anacron (desktop e laptop Ubuntu), 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 seu computador funcione 24 horas por dia, 7 dias por semana (como nossos laptops) e executará os scripts que perdeu porque o sistema estava fora do ar.
Você pode tentar com este exemplo usar tempos aleatórios antes de executar o comando:
#!/bin/bash
# start time
date +"%H:%M:%S"
# sleep for 5 seconds
sleep $(shuf -i 1-25 -n 1)
# end time
date +"%H:%M:%S"
Que tal criar um script que reescreve o crontab todos os dias?
Sei que é um segmento mais antigo, mas quero adicionar uma coisa relacionada a valores aleatórios que uso muito. Em vez de usar a variável $ RANDOM com um intervalo fixo e limitado, geralmente crio valores aleatórios de intervalo arbitrário no shell com
dd if=/dev/urandom bs=4 count=1 2>/dev/null | od -N4 -t u4 -A none
então você pode fazer, por exemplo,
FULLRANDOM=$(dd if=/dev/urandom bs=4 count=1 2>/dev/null | od -N4 -t u4 -A none)
e superar algumas das restrições que foram discutidas neste tópico.
~$info dd
e posso entender o que está acontecendo no lado esquerdo |
, mas não consigo distinguir o lado direito. Então, para mim e outros interessados na overcoming some restrictions
geração de valor aleatório, por que não reservar um momento para explicar o RHS e fazer um argumento mais forte para usar sua abordagem. A profundidade da explicação deixa as pessoas confortáveis com o processo que você sugere e seus benefícios. Obrigado.