a melhor maneira é usar flock
em vez de um pidfile. verifique a manpage: flock (1) . A vantagem é que, não importa como um processo termine / morra, a fechadura desaparece.
Existe uma maneira de executar um script a cada minuto (ou 2, ou 5, etc), mas somente se ele ainda não estiver em execução?
Temos um conjunto de scripts que precisam ser executados a cada minuto. Às vezes eles podem começar e terminar em um segundo, outras vezes podem durar 5 minutos.
Nosso modo atual de evitar execuções simultâneas é definir um sinalizador is_running
em cada script e sair, se ainda estiver habilitado. Mas isso é um pouco não confiável (isto é, erros fatais podem fazer com que o sinalizador permaneça ativado mesmo depois que o script é interrompido).
Poderíamos escrever nosso próprio gerenciador, mas estou imaginando se existe uma solução mais moderna que já exista.
a melhor maneira é usar flock
em vez de um pidfile. verifique a manpage: flock (1) . A vantagem é que, não importa como um processo termine / morra, a fechadura desaparece.
Eu tenderia a concordar com a resposta do arquivo pid da Warner. No entanto, o seguinte recurso do Anacron faz isso?
-s
Serialize execution of jobs. Anacron will not start a new job before the previous one finished.
Eu mesmo não testei, não acho a documentação do anacron completa o suficiente ...
Se você quer ser particularmente preguiçoso ;-) Você pode apenas fazer o script sair se o greping através da saída ps retornar o processo como em execução. Mas um arquivo lock / pid é melhor.
Essa é a solução adequada para essa abordagem. Normalmente, um arquivo pid seria usado e um teste de pid seria feito contra o processo para garantir sua execução. Se obsoleto, o arquivo de bloqueio seria removido e o processo seria executado de qualquer maneira.
Qualquer inteligência adicional seria tipicamente escrita no próprio software, como um daemon, ao invés de rodar no cron.
Se os seus scripts forem codificados em um idioma que suporte o flock (2) syscall, você também poderá agrupar () um arquivo de bloqueio com uma chamada de função. Exemplo:
Se você está preso ao Bash ou outra linguagem de script que não suporta isso, a solução já proposta com flock (1 ) também está bem.
P.S. Em qualquer caso, você deve criar um arquivo de bloqueio separado apenas uma vez (se já não existir) e nunca excluí-lo. O diretório "/ var / lock" é um bom lugar para esses arquivos.
Esta é uma solução se o seu script é executado em python (ou você poderia criar um comando python para executar antes do próximo comando) - Eu encontrei este problema exato na semana passada, e embora eu tenha encontrado algumas boas soluções, decidi faça um pacote python muito simples e limpo e carregue-o no PyPI. Você certamente pode bloquear __file__
para não ter que pensar em fornecer um nome de recurso personalizado para bloquear.
Instale com: pip install quicklock
Usar é extremamente simples:
[nate@Nates-MacBook-Pro-3 ~/live] python
Python 2.7.6 (default, Sep 9 2014, 15:04:36)
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.39)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from quicklock import singleton
>>> # Let's create a lock so that only one instance of a script will run
...
>>> singleton('hello world')
>>>
>>> # Let's try to do that again, this should fail
...
>>> singleton('hello world')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/nate/live/gallery/env/lib/python2.7/site-packages/quicklock/quicklock.py", line 47, in singleton
raise RuntimeError('Resource <{}> is currently locked by <Process {}: "{}">'.format(resource, other_process.pid, other_process.name()))
RuntimeError: Resource <hello world> is currently locked by <Process 24801: "python">
>>>
>>> # But if we quit this process, we release the lock automatically
...
>>> ^D
[nate@Nates-MacBook-Pro-3 ~/live] python
Python 2.7.6 (default, Sep 9 2014, 15:04:36)
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.39)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from quicklock import singleton
>>> singleton('hello world')
>>>
>>> # No exception was thrown, we own 'hello world'!
Dê uma olhada: link