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?


fonte
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
Rich Homolka
fonte
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
harrymc
fonte
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
Linker3000
fonte
3

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

flock é um utilitário que pode ser usado.

Pausado até novo aviso.
fonte
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.

Dave Sherohman
fonte
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.

Vinodh Krishnaraju
fonte