A questão não está muito bem colocada. Em última análise, você deseja distribuir 20 pontos no eixo do tempo entre 9h e 11h. Mas existem restrições quanto à diferença de tempo mínima? É aceitável não fazer nada entre 9h e 10h30? A única maneira de fazer isso de maneira aceitável parece ser a ideia de Klaus: selecione 20 vezes às 09:00, o que permite que você cumpra qualquer restrição que possa ter, e agende as coisas com "at".
David Tonhofer
Respostas:
37
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:
09***/path/to/bashscript
e em / path / to / bashscript:
#!/bin/bash
maxdelay=$((14*60))# 14 hours from 9am to 11pm, converted to minutesfor((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 scriptdone
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.
Você pode tornar as atribuições aritméticas mais legíveis largando o cifrão e movendo os parênteses duplos para a esquerda (por exemplo, ((maxdelay = 14 * 60))ou ((delay = $RANDOM % maxdelay))). O sleepargumento ainda precisa ser do jeito que você tem (embora você possa adicionar espaços, se desejar).
Pausado até novo aviso.
Isso funcionou para mim também. Meu script bash personalizado é parecido com o abaixo sleep $[ ( $RANDOM % 60 ) + 1 ]s && some_script.sh
Shyam Habarakada,
Estou faltando alguma coisa ou o atraso máximo deve ser definido como maxdelay = $ ((14 *
60/20
@jenishSakhiya Os atrasos aleatórios para cada uma das 20 execuções são absolutos (bem, começando às 9h), não em relação a outra corrida. Ou seja, se um dos atrasos aleatórios chegar a 13 horas, isso significa que ele será executado às 22h (13 horas após as 9h), e não 13 horas depois de qualquer uma das outras execuções.
Gordon Davisson
138
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:
$ {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!):
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.
Eu gosto da resposta tardia. Mas se você está tentando gerar um número inteiro aleatório distribuído uniformemente no intervalo de 10 a 99, e a saída de RANDOM é de 0 a 32.767, por que não faria isso $[(RANDOM/368)+10]?
jsdalton
3
@jsdalton: O operador de módulo não seria melhor? $((RANDOM % 90 + 10))Teste:for i in {0..9999}; do echo $((RANDOM % 90 + 10)); done | sort | uniq -c
geon
5
Em muitos sistemas cron não usa o bash por padrão, então ele poderia ser melhor para evitar a Bashismo $RANDOM: sleep $(( $(od -N1 -tuC -An /dev/urandom) \% 90 ))m.
pabouk de
9
Certifique-se de que crontab está usando bashantes de usar $RANDOM. Se tiver vixie-cron(parece ser o meu caso no Ubuntu), você pode adicionar SHELL=/bin/bashao topo. Existem mais alternativas para outras versões do cron aqui: superuser.com/a/264541/260350
DaAwesomeP
1
Quando uso a primeira sugestão acima, recebo crontab: errors in crontab file, can't install. Do you want to retry the same edit?ajuda
Seano
72
Então, estou usando o seguinte para executar um comando entre 1h e 330h
Eu adoraria usar a variável RANDOM_DELAY, mas não consigo encontrar nenhuma dica na página de manual do crontab (5) no Ubuntu 14.04.4 LTS.
Exocom
Isso é lamentável. Eu me pergunto se não há suporte lá. Eu vejo isso documentado naquela página de manual no Centos 7 e Arch Linux.
Micah Elliott
9
esta parece ser a resposta correta, mas você pode dar um exemplo?
chovy
14
Observe que RANDOM_DELAYé estabelecido uma vez e permanece constante durante todo o tempo de execução do daemon.
Maciej Swic
5
A RANDOM_DELAYbandeira é um recurso do cronie-crond enquanto o Ubuntu parece estar em execução, vixie-cronmas não tem essa bandeira.
kravietz
7
Meu primeiro pensamento seria criar um cron job lançando 20 agendados aleatoriamente em jobs. O atutilitário (http://unixhelp.ed.ac.uk/CGI/man-cgi?at) é usado para executar comandos em um horário especificado.
Se alguém se perguntar, como eu:% N fornece nanos atuais, mas algumas páginas de manual não têm informações sobre isso. Esta é uma solução muito inteligente para pessoas que precisam apenas de "alguma aleatoriedade" facilmente por comando.
Thorsten Schöning,
Além das advertências já abordadas em outro lugar, isso só funcionará se você tiver GNU 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).
tripleee
4
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 é:
Eu tentei de tudo e ainda não funcionou para mim. Você postou explicou o porquê, obrigado!
marlar
$[ ... ]é uma sintaxe obsoleta desde waaaay de volta; para qualquer coisa deste milênio, você prefere $((RANDOM\%90))mqual é a sintaxe compatível com POSIX (mas RANDOMé claro que ainda é apenas Bash).
tripleee
1
at -f [file] [timespec]
ou
echo [command] | at [timespec]
ou
at [timespec]... e especificações interativas como scripta gravação de.
Comando
Em executa o texto fornecido em stdin ou no arquivo especificado por -f [file].
De tempo de 24 horas como int quatro dígitos, por exemplo 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 UTCo argumento opcional de fuso horário.
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 a análise bash fazendo uma pré-pendente echoe 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 atqe o conteúdo do trabalho (variáveis de ambiente, configuração e comando / script) com at -c [jobid].
Nota
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.
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.
Não contorne o sistema de reputação postando comentários como respostas. No entanto, seu comentário parece bom o suficiente para ser realmente uma resposta. Eu recomendo remover " Eu não tenho representante para adicionar um comentário, mas ".
Ted Lyngmo
1
Acabei de revisar esta resposta e perdi a parte em que você está fazendo uma pergunta de volta no final (trabalho desleixado da minha parte). Não faça perguntas nas respostas. Poste sua própria pergunta para perguntas que você tem. Transformei sua semi-pergunta em algo que poderia passar por uma resposta.
Ted Lyngmo
1
Entendi! THX. Serei mais cuidadoso da próxima vez, nenhuma má intenção foi intencional.
melofellow
1
Tenho certeza de que você não teve más intenções e não precisa ser excessivamente cuidadoso. Você delineou uma possível solução - e tropeçou um pouco no final. Não se preocupe!
Ted Lyngmo
0
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=12>/dev/null | od -N4 -t u4 -A none
então você pode fazer, por exemplo,
FULLRANDOM=$(dd if=/dev/urandom bs=4 count=12>/dev/null | od -N4 -t u4 -A none)
e superar algumas das restrições que foram discutidas neste tópico.
Bem-vindo ao SO. Bem, discussão antiga ou não, isso me levou a ~$info dde 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 restrictionsgeraçã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.
Chris
Ah ok. od aka "octal dump" pega um arquivo ou stdin e despeja os dados binários em uma forma legível por humanos. Queremos que nosso número seja mostrado como um decimal sem sinal (-t u4) e não queremos o índice de endereço (-A nenhum). O -N4 é redundante porque pegamos apenas 4 bytes, mas também não faz mal. Espero que isso explique ...
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:
e em / path / to / bashscript:
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.
fonte
((maxdelay = 14 * 60))
ou((delay = $RANDOM % maxdelay))
). Osleep
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:
$ {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!):
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.
fonte
$[(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á usandobash
antes de usar$RANDOM
. Se tivervixie-cron
(parece ser o meu caso no Ubuntu), você pode adicionarSHELL=/bin/bash
ao topo. Existem mais alternativas para outras versões do cron aqui: superuser.com/a/264541/260350crontab: errors in crontab file, can't install. Do you want to retry the same edit?
ajudaEntão, estou usando o seguinte para executar um comando entre 1h e 330h
Isso tem cuidado de minhas necessidades aleatórias para mim. Isso dá 9000 segundos == 150 minutos == 2,5 horas
fonte
Cron oferece um
RANDOM_DELAY
variável. Vejacrontab(5)
para detalhes.Isso é visto comumente em
anacron
empregos, mas também pode ser útil em acrontab
.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.
fonte
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.fonte
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
fonte
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 é:
fonte
$[ ... ]
é 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 (masRANDOM
é claro que ainda é apenas Bash).at -f [file] [timespec]
ou
echo [command] | at [timespec]
ou
at [timespec]
... e especificações interativas comoscript
a gravação de.Comando
Em executa o texto fornecido em stdin ou no arquivo especificado por
-f [file]
.Timespec
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.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 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) comat -c [jobid]
.Nota
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.
fonte
Para quem pesquisou o caminho até aqui:
Se você estiver usando anacron (desktop e laptop Ubuntu), você pode editar
e adicione
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.
fonte
Você pode tentar com este exemplo usar tempos aleatórios antes de executar o comando:
fonte
Que tal criar um script que reescreve o crontab todos os dias?
fonte
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
então você pode fazer, por exemplo,
e superar algumas das restrições que foram discutidas neste tópico.
fonte
~$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 naovercoming 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.