Posso executar um trabalho cron com mais frequência do que a cada minuto?

44

É possível executar uma tarefa cron a cada 30 segundos sem um comando de suspensão?

user15336
fonte
4
Qual é a sua intenção? O cron é a ferramenta certa para isso?
Manuel Faux
Boa pergunta.
Preet Sangha
Por exemplo, atualmente estou usando o cron para alterar minha imagem de plano de fundo da área de trabalho, para contornar as limitações do alternador de imagem de plano de fundo nativo (não mergulhando em subdiretórios). Se eu quisesse mudar mais de uma vez por minuto, encontraria essa limitação do cron. (embora a BG comutador nativa tem a mesma limitação)
Donquixote

Respostas:

36

Se sua tarefa precisar ser executada com tanta frequência, o cron é a ferramenta errada. Além de simplesmente não iniciar trabalhos com tanta frequência, você também corre o risco de ter problemas sérios se o trabalho demorar mais para ser executado do que o intervalo entre os lançamentos. Reescreva sua tarefa para daemonize e execute persistentemente, em seguida, inicie-a no cron, se necessário (assegurando-se de que não será reiniciada se já estiver em execução).

crepúsculo
fonte
18
A parte "você também arrisca alguns problemas sérios se o trabalho demorar mais para ser executado do que o intervalo entre lançamentos". não é verdade e, se fosse, se aplicaria igualmente a tarefas executadas a cada 5 minutos, a cada hora ou a cada mês. Esse problema tem soluções (usando um pidfile ou qualquer outra coisa e verificando se o trabalho já está sendo executado antes de executá-lo). Portanto, o problema é que o cron simplesmente não permite essa frequência, mas é incorreto dizer que há algo intrinsecamente errado na execução de uma tarefa a cada menos de um minuto.
Matteo
2
Eu quis dizer se você não usa um pidfile. Se o seu trabalho for executado a cada X minutos e demorar mais de X minutos para terminar, você terminará com os trabalhos empilhados. Se o seu trabalho também estiver limitado por algum tipo de recurso (CPU, largura de banda da rede / disco, etc.), a execução de mais de uma vez levará mais tempo para terminar e, eventualmente, o computador se transformará em uma bagunça.
duskwuff
2
Você pode usar run-onepara garantir que um programa / mesmo um script PHP não esteja iniciando uma instância duplicada. sudo apt-get install run-onee chame-o porrun-one <normal command>
kouton
3
Como mostram as respostas mais abaixo, é muito bem possível, embora um pouco imprudente. Por que você está fazendo errado !!!! a resposta aceita aqui, quando não responde à pergunta?
Alguém
@ Mantriur Porque o autor da pergunta achou útil e marcou como resposta aceita? :) Mas, falando sério, você já identificou o problema: muitas das outras respostas contemporâneas propuseram soluções hackísticas que não seriam prudentes usar em um sistema de produção. (Além disso, mantenha em mente que várias das outras respostas só mostrou-se anos após a pergunta foi feita, então eles não estavam disponíveis para aceitar ainda!)
duskwuff
37

Candidato ao uso mais criativo de um comando do Linux:

nohup watch -n 30 --precise yourprog >/dev/null &

Se yourprogconsiste em:

date +%M.%S.%N >> yourprog.out

então yourprog.outpode parecer com:

50.51.857291267
51.21.840818353
51.51.840910204
52.21.840513307
52.51.842455224
53.21.841195858
53.51.841407587
54.21.840629676

indicando um bom nível de precisão.

Aqui está uma explicação das partes do comando:

  • nohup- Isso impede que o comando a seguir, watchneste caso, saia quando o terminal sair.
  • watch- Este programa executa um comando repetidamente. Normalmente, a primeira tela cheia de saída do comando é exibida sempre que o comando é watchexecutado.
  • -n 30- O intervalo no qual executar o comando. Nesse caso, é a cada trinta segundos.
  • --precise- Sem essa opção, watchexecuta o comando após o intervalo de segundos. Com ele, cada início do comando começa no intervalo, se possível. Se essa opção não fosse especificada no exemplo, os tempos seriam posteriores e posteriores por mais de 30 segundos, devido ao tempo necessário para iniciar e executar o comando ( yourprog).
  • yourprog- O programa ou linha de comando para watchexecutar. Se a linha de comando contiver caracteres especiais para o shell (por exemplo, espaço ou ponto e vírgula), ela precisará ser citada.
  • >/dev/null- O maior que redireciona a saída do comando que está sendo executado watchpara um arquivo /dev/null,. Esse arquivo descarta qualquer dado gravado nele. Isso evita que a saída seja gravada na tela ou, como nohupestá sendo usada, evita que a saída seja enviada para um arquivo chamado nohup.out.
  • &- O watchcomando é executado em segundo plano e o controle é retornado ao terminal ou processo pai.

Observe que nohupo redirecionamento da saída e o &operador de controle em segundo plano não são específicos watch.

Aqui está uma explicação do yourprogscript de exemplo :

  • date- Mostra a data e / ou hora atuais. Também pode configurá-los.
  • +%M.%S.%N- Isso especifica o formato de saída datea ser usado. %Mé o minuto atual, %Sé o segundo atual e %Né o nanossegundo atual.
  • >> yourprog.out- Isso redireciona a saída do datecomando para um arquivo chamado yourprog.out. O duplo maior que faz com que a saída seja anexada ao arquivo em cada chamada, em vez de o conteúdo anterior ser substituído.

Editar :

Possivelmente outra coisa que poderia ser abusada (ou talvez seja um uso legítimo) são os temporizadores do sistema.

Veja systemd / Timers como uma substituição cron e Cron vs systemd timers .

Vou tentar postar um exemplo em breve.

Dennis Williamson
fonte
6
Eu estou dando uma de rosto puro
Matt Simmons
2
Seria bom ter um pouco mais de explicação com esta resposta. O comando nohup é novo para mim. A internet me diz que é para ignorar o sinal de desligamento. O que ainda me deixa confusa.
23916 donquixote
2
@donquixote: É importante reconhecer que o comando como um todo na minha resposta não é uma coisa recomendada, portanto, o uso da palavra "uso indevido". No entanto, para esclarecer um pouco as coisas para você, uma vez que existem técnicas úteis incluídas, tentarei descrever algumas. Isso &faz com que o comando seja executado em segundo plano, retornando o controle ao prompt de comando imediatamente. O uso do nohupcomando faz com que o processo em segundo plano (neste caso watch) ignore o sinal de interrupção que é enviado quando o shell sai, como quando você fecha o terminal. ...
Dennis Williamson
1
... Redirecionar a saída usando >/dev/nullfaz com que a saída seja descartada e impede a criação de um nohup.outarquivo que seria criado quando a saída padrão é um terminal.
Dennis Williamson
1
@donquixote: Daqui a apenas 30 segundos, a cada 30 segundos. O resto é que ele seja executado autônoma em segundo plano para ser mais parecido com o cron. Se você quisesse usar sleep, seria necessário escrever um loop para que o processo se repetisse ( watchisso se repete para você, também cron). Você ainda precisaria nohupe &. Um problema adicional sleepseria o desvio do tempo. A --preciseopção de watchevita isso. Sem ele ou ao usar sleepem um loop, o intervalo de tempo tem o tempo que leva para os comandos ou script a ser executado adicionados a ele para cada corrida ganha cada vez mais tarde do que o ...
Dennis Williamson
13

O Cron foi projetado para acordar a cada minuto, portanto, não é possível fazê-lo sem alguns hackers, por exemplo, dormir como você mencionou.

Balázs Pozsár
fonte
10
* * * * * /path/to/program
* * * * * sleep 30; /path/to/program

Não se esqueça de escrever algo em seu programa para que ele saia se uma instância anterior já estiver em execução.

#!/bin/sh

if ln -s "pid=$$" /var/pid/myscript.pid; then
  trap "rm /var/pid/myscript.pid" 0 1 2 3 15
else
  echo "Already running, or stale lockfile." >&2
  exit 1
fi

Obviamente, isso ainda deixa uma oportunidade muito pequena de falha, portanto, pesquise no Google por uma solução melhor aplicável ao seu ambiente.

ghoti
fonte
foi solicitado:without a sleep command
philippe
10
Outros visitantes encontrar esta questão não se importam se o comando sono é usado :)
Donquixote
8

Você pode fazer isso com software de terceiros.

Uma opção que funcionou bem para mim é o frequ-cron

Permite precisão de milissegundos e oferece a opção de adiar a próxima execução até que a atual seja encerrada.

thatjuan
fonte
1
O Frequent-cron também funcionou bem para nós e alimenta muitos de nossos sistemas de produção. Nós nunca tivemos um problema com isso.
Homer6
2

Eu teria algumas preocupações:

(1) às vezes um sistema fica ocupado e não pode iniciar as coisas exatamente no ponto de 30 segundos, é possível que ao mesmo tempo em que você esteja executando um trabalho, outro trabalho seja exibido e você tenha 2 (ou mais) trabalhos fazendo o mesmo coisa. Dependendo do script, pode haver alguma interferência significativa aqui. Portanto, a codificação desse script deve conter algum código para garantir que apenas uma instância do script fornecido esteja sendo executada ao mesmo tempo.

(2) O script pode ter muita sobrecarga e consumir mais recursos do sistema do que você deseja. Isso é verdade se você estiver competindo contra muitas outras atividades do sistema.

Assim, como um pôster colocou, neste caso, eu consideraria seriamente colocar um daemon em execução com processos adicionais para garantir que ele permaneça em execução, se for de importância crítica para suas operações.

mdpc
fonte
1

minha solução mais simples e favorita para esta tarefa:

entrada cron:
* * * * * flock -w0 /path/to/script /path/to/script

roteiro:
while true;do echo doing something; sleep 10s;done

alternativa preguiçosa: :)

* * * * * flock -w0 /path/to/log watch -n 10 echo doing >> /path/to/log

ou

* * * * * flock -w0 /path/to/log watch -n 10 /path/to/script

profissionais

  • o uso do flockcomando evita a execução do script por várias instâncias ao mesmo tempo. Pode ser muito importante na maioria dos casos.
  • flocke watchcomandos está disponível na maioria das instalações do Linux

contras

  • a interrupção desse tipo de "Serviço" precisa de duas etapas
    • comentar a entrada cron
    • mate o script ou o watchcomando
asvany
fonte
2
Alguém pode explicar isso para um novato no Linux - com prós e contras? Obrigado ..
a20
@ asvany Acho que gosto dessa solução, mas como a20, você poderia postar alguma explicação para o Linux "verde", por favor? ty.
JoelAZ 16/03
0

Uma solução, se for para seu próprio script ou se você puder envolvê-lo:

  1. Obtenha e lembre-se da hora de início.
  2. Se um arquivo de bloqueio, que você tocará mais tarde, estiver presente e o script não estiver em execução por 60 segundos, aguarde um segundo e verifique novamente. (por exemplo, enquanto estiver dormindo)
  3. Se o arquivo de bloqueio ainda estiver presente após decorridos 60 segundos, saia com um aviso de bloqueio obsoleto.
  4. Toque no arquivo de bloqueio.
  5. Enquanto o script não estiver em execução por 60 segundos, faça um loop na sua tarefa real com a duração de sono desejada.
  6. Excluir arquivo de bloqueio.
  7. Adicione como cron minuciosamente.
  8. Bob é seu tio.

Menos dor de cabeça do que construir e monitorar um daemon.

* Se você estiver usando PHP, lembre-se de clearstatcache ().

Alguém
fonte