cron: exécuter un processus mais uniquement s'il n'est pas en cours d'exécution?


11

Existe-t-il un moyen pour moi de dire à cron d'exécuter une application MAIS de ne pas l'exécuter si un processus existe déjà?

linux  cron 

Pourriez-vous préciser si l'application ne doit pas s'exécuter si elle est déjà en cours d'exécution ou si un processus différent est déjà en cours d'exécution. Merci
Linker3000

Réponses:


23

la manière la plus simple, utilisez pgrep

dans crontab:

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

J'adore la simplicité de cette réponse. Pour info, vous devriez pouvoir ajouter l'indicateur -f à pgrep, et vous pouvez ensuite vérifier le nom complet du processus, ce qui est utile si vous souhaitez également inspecter les arguments du processus dans le cadre de votre condition.
Craig Sefton

6
Non, vous ne pouvez pas utiliser le drapeau -f avec pgrep dans un cronjob. La raison en est que vous vous comparerez au script shell utilisé pour exécuter le cronjob lui-même.
CpnCrunch

Lorsque vous exécutez un processus GUI avec cron, ajoutez-le avec export DISPLAY=:0pour éviter les Could not connect to displayerreurs. * * * * * export DISPLAY=:0 && pgrep processname > /dev/null || /path/to/processname -args0 -args1
Benjam

9

Exécutez un script, au lieu de directement le programme. Il existe de nombreuses possibilités. Par exemple :

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

1
Pour info - l'utilisation de variables scalaires pour stocker des listes d'arguments est considérée comme une mauvaise pratique. Voir mywiki.wooledge.org/BashFAQ/050 pour un exemple de cas où il échoue.
Charles Duffy

... de même, pgrep myprog; if [ $? -ne 0 ]; then ...serait mieux écrit commeif ! pgrep myprog; then ...
Charles Duffy

... ce dernier style est non seulement plus lisible, mais aussi moins sujet aux erreurs: il est facile de perturber involontairement la valeur de $?, par exemple en ajoutant des messages de journal ou une gestion des erreurs entre les lignes.
Charles Duffy

7

Ce script ne s'exécutera pas à nouveau si l'instance précédente n'est pas terminée. Si vous ne souhaitez pas exécuter quelque chose si un autre processus spécifique est en cours d'exécution, consultez le script de 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

Vous pouvez utiliser un fichier de verrouillage dans votre script, mais veuillez consulter Gestion des processus .

flock est un utilitaire qui peut être utilisé.


bon! maintenant rsync sur cette ligne lente peut prendre tout le temps nécessaire, se déclenchant dans les 5 minutes suivant la mise en ligne de l'hôte client sans intervention manuelle:*/5 * * * * root flock /run/shm rsync -auhx --numeric-ids -e "ssh -T -c arcfour128 -o Compression=no -x" [source] [user]@[host]:[dest]
eMPee584

1

Ceci est généralement géré par le programme lui-même plutôt que par cron. Il existe deux techniques standard pour cela:

1) grepla sortie de pspour voir si un processus de ce nom est déjà en cours d'exécution

2) Au démarrage, vérifiez d'abord l'existence d'un fichier pid (identifiant de processus), généralement sur /var/run/program_name.pid, et, s'il existe, lisez le pid du fichier et vérifiez si ce processus existe toujours; si c'est le cas, refusez de commencer. Si le fichier pid n'existe pas ou que le pid dans le fichier a disparu, créez un fichier pid, écrivez-y votre identifiant de processus et continuez avec un démarrage normal.

Bien qu'il soit techniquement possible d'écrire des tuyaux bash qui feront l'un ou l'autre directement dans votre crontab, il est préférable de les ajouter au programme en cours de démarrage (afin qu'ils s'appliquent quelle que soit la façon dont il démarre) ou d'écrire un script wrapper dans gérer cela, comme l'a suggéré harrymc.


0

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

J'ai réutilisé la réponse ci-dessus avec une amélioration de la correspondance des modèles. pgrep sans l'option f ne correspond pas au modèle de processus. Pourtant, il y a un problème avec l'utilisation de l'option f. Avec l'option f, le shell engendrant le cron est toujours mis en correspondance et retourne son pid donc le processus n'est jamais redémarré.

L'ajout d'un [] autour d'une des lettres correspond uniquement au processus et le pid du shell cron n'est pas renvoyé.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.