Existe uma maneira de eu dizer ao cron para executar um aplicativo, mas não o execute se já existir um processo?
Existe uma maneira de eu dizer ao cron para executar um aplicativo, mas não o execute se já existir um processo?
Respostas:
da maneira mais simples, use o pgrep
no crontab:
* * * * * pgrep processname > /dev/null || /path/to/processname -args0 -args1
export DISPLAY=:0
para evitar Could not connect to display
erros. * * * * * export DISPLAY=:0 && pgrep processname > /dev/null || /path/to/processname -args0 -args1
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
pgrep myprog; if [ $? -ne 0 ]; then ...
seria melhor escrito comoif ! pgrep myprog; then ...
$?
, por exemplo, adicionando mensagens de log ou tratamento de erros entre linhas.
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
Você pode usar um arquivo de bloqueio em seu script, mas consulte Gerenciamento de Processos .
flock
é um utilitário que pode ser usado.
*/5 * * * * root flock /run/shm rsync -auhx --numeric-ids -e "ssh -T -c arcfour128 -o Compression=no -x" [source] [user]@[host]:[dest]
Isso geralmente é tratado pelo próprio programa e não por cron
. Existem duas técnicas padrão para isso:
1) grep
a saída de ps
para 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.pid
e, 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.
* * * * * 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.