Se a condição for verdadeira, durma o cron job por 5 minutos

6

Eu tenho um script definido para ser executado a cada minuto. Mas no script que mencionamos, se uma condição for verdadeira, o script terá que dormir por 5 minutos. Como isso pode afetar o crontab? O script estará em modo de espera por 5 min, ou será executado novamente conforme definido no crontab para cada 1min?

    
por Ravikanth 21.01.2015 / 08:19

3 respostas

19

Você tem duas opções para ganhar isso. Normalmente, o cron não importa se a instância anterior da tarefa ainda está em execução.

Opção 1:

Escreva um arquivo de bloqueio no início do script e exclua-o quando terminar. Em seguida, uma verificação no início do script verifica se o arquivo existe e, se sim, o script termina sem fazer algo. Isso poderia, por exemplo, ficar assim:

# if the file exists ('-e') end the script:
[ -e "/var/lock/myscript.pid" ] && exit

# if not create the file:
touch /var/lock/myscript.pid

...
# do whatever the script does.
# if condition
sleep 300 # wait 5 min
...

# remove the file when the script finishes:
rm /var/lock/myscript.pid

Opção 2:

Há também uma utilidade para isso. É chamado run-one . A partir do manpage:

run-one - run just one instance at a time of some command and unique set of arguments (useful for cronjobs, eg)

O cronjob poderia ficar assim:

* * * * *   /usr/bin/run-one /path/to/myscript
    
por 21.01.2015 / 08:35
3

Eu fiz algo parecido - pausando um script se algo aconteceu, mas não o executei do cron. Em vez disso, eu tinha um script de shell que continuamente se executaria novamente. No meu caso, verifiquei a média de carga e fiz uma pausa por um minuto, se ela estava "muito alta". Foi tudo bem, eu fiz as coisas que eu precisava e depois parei por um tempo bem menor.

Isto também tem as vantagens de apenas um roteiro rodar, e você também pode re-executá-lo com mais freqüência do que a cada minuto, que é a freqüência mínima do cron.

#!/bin/bash

i_should_sleep() {
  if [ *condition* ]
  then
    return 0
  else
    return 1
  fi
}

if i_should_sleep; then
    sleep 300
    exec $0 $@
fi

nice COMMAND # run the action we really want to do

sleep 60  # or less than a minute, to run more often

exec $0 $@

Para iniciá-lo, você criaria um trabalho Upstart ou init.d ou algo similar.

    
por 21.01.2015 / 14:16
3

Com o crontab, você não pode fazer isso, mas você pode fazer isso com um pouco de extensão do seu script. Estou pensando no seguinte pseudo-código:

#!/bin/bash
if ...temporary_file_exists
then
  if ...tmp_is_older_as_5_minute...
  then
     delete tmp
  else
     exit
  fi
fi

...
if "${condition}"
then
  touch $temporary_file
  exit
fi

...normal behavior of your script...

O que isso faz? O principal problema dos scripts cron, é que você não pode ter facilmente uma memória persistente entre suas execuções. Você precisa fazer isso sempre com métodos ad hoc. No mundo de scripts unix, arquivos temporários são soluções muito comuns para isso, e você usa a existência (e o tempo de mudança) de um arquivo temporário para saber qual é a situação real.

    
por 21.01.2015 / 08:38

Tags