cron: executa um processo, mas apenas se não estiver em execução?


11

Existe uma maneira de eu dizer ao cron para executar um aplicativo, mas não o execute se já existir um processo?

linux  cron 

Você esclareceria se o aplicativo não deve ser executado se já estiver em execução ou se um processo diferente já estiver em execução. Graças
Linker3000

Respostas:


23

da maneira mais simples, use o pgrep

no crontab:

* * * * * pgrep processname > /dev/null || /path/to/processname -args0 -args1

Ame a simplicidade desta resposta. Para sua informação, você poderá adicionar o sinalizador -f ao pgrep e poderá verificar o nome completo do processo, o que é útil se você também deseja inspecionar os argumentos do processo como parte de sua condição.
Craig Sefton

6
Não, você não pode usar o sinalizador -f com pgrep dentro de um cronjob. O motivo é que você comparará com o script de shell usado para executar o cronjob em si.
CpnCrunch

Ao executar um processo da GUI com cron, inclua com export DISPLAY=:0para evitar Could not connect to displayerros. * * * * * export DISPLAY=:0 && pgrep processname > /dev/null || /path/to/processname -args0 -args1
Benjam

9

Execute um script, em vez de diretamente o programa. Existem muitas possibilidades. Por exemplo :

MYPROG="myprog"
RESTART="myprog params"
PGREP="/usr/bin/pgrep"
# find myprog pid
$PGREP ${MYPROG}
# if not running
if [ $? -ne 0 ]
then
   $RESTART
fi

1
Para sua informação, usar variáveis ​​escalares para armazenar listas de argumentos é considerado uma prática ruim. Veja mywiki.wooledge.org/BashFAQ/050 para obter um exemplo de caso em que falha.
Charles Duffy

... da mesma forma, pgrep myprog; if [ $? -ne 0 ]; then ...seria melhor escrito comoif ! pgrep myprog; then ...
Charles Duffy

... esse último estilo não é apenas mais legível, mas também menos propenso a erros: é fácil interromper acidentalmente o valor de $?, por exemplo, adicionando mensagens de log ou tratamento de erros entre linhas.
Charles Duffy

7

Este script não será executado novamente se a instância anterior não tiver sido concluída. Se você não deseja executar algo se outro processo específico estiver em execução, consulte o script do harrymc.

DATE=`date +%c`;
ME=`basename "$0"`;
LCK="./${ME}.LCK";
exec 8>$LCK;

if flock -n -x 8; then
  echo ""
  echo "Starting your script..."
  echo ""

[PUT YOUR STUFF HERE]

  echo ""
  echo "Script started  $DATE";
  echo "Script finished `date +%c`";
else
  echo "Script NOT started - previous one still running at $DATE";
fi

3

Você pode usar um arquivo de bloqueio em seu script, mas consulte Gerenciamento de Processos .

flock é um utilitário que pode ser usado.


um bom! agora rsync sobre esta linha lenta pode tomar todo o tempo que ele precisa, disparando dentro de 5 minutos do host cliente que vem em linha sem intervenção manual:*/5 * * * * root flock /run/shm rsync -auhx --numeric-ids -e "ssh -T -c arcfour128 -o Compression=no -x" [source] [user]@[host]:[dest]
eMPee584

1

Isso geralmente é tratado pelo próprio programa e não por cron. Existem duas técnicas padrão para isso:

1) grepa saída de pspara ver se já existe um processo com esse nome em execução

2) Na inicialização, verifique primeiro a existência de um arquivo pid (identificação do processo), geralmente em /var/run/program_name.pide, se existir, leia o pid do arquivo e verifique se esse processo ainda existe; se isso acontecer, recuse-se a começar. Se o arquivo pid não existir ou o pid no arquivo desaparecer, crie um arquivo pid, escreva sua identificação de processo e continue com a inicialização normal.

Embora seja tecnicamente possível escrever pipes bash que os executem diretamente no seu crontab, é melhor adicioná-los ao programa que está sendo iniciado (para que eles sejam aplicados independentemente de como é iniciado) ou gravar um script de wrapper no lidar com isso, como harrymc sugerido.


0

* * * * * pgrep -f "[p]attern" > /dev/null || /path/to/processname -args0 -args1

Reutilizei a resposta acima com uma melhoria na correspondência de padrões. O pgrep sem a opção f não corresponde ao padrão do processo. No entanto, há um problema com o uso da opção f. Com a opção f, o shell que gera o cron sempre é correspondido e retorna seu pid, portanto, o processo nunca é reiniciado.

Adicionar um [] ao redor de um padrão de letras corresponde apenas ao processo e o pid do cron shell não é retornado.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.