cron: einen Prozess ausführen, aber nur, wenn er nicht ausgeführt wird?


11

Gibt es eine Möglichkeit für mich, cron anzuweisen, eine App auszuführen, ABER sie nicht auszuführen, wenn bereits ein Prozess vorhanden ist?

linux  cron 

Würden Sie klären, ob die App nicht ausgeführt werden soll, wenn sie bereits ausgeführt wird oder wenn bereits ein anderer Prozess ausgeführt wird? Danke
Linker3000

Antworten:


23

Verwenden Sie am einfachsten pgrep

in crontab:

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

Ich liebe die Einfachheit dieser Antwort. Zu Ihrer Information, Sie sollten in der Lage sein, das Flag -f zu pgrep hinzuzufügen, und Sie können dann den vollständigen Prozessnamen überprüfen. Dies ist nützlich, wenn Sie auch die Argumente für den Prozess als Teil Ihrer Bedingung überprüfen möchten.
Craig Sefton

6
Nein, Sie können das Flag -f nicht mit pgrep in einem Cronjob verwenden. Der Grund dafür ist, dass Sie mit dem Shell-Skript übereinstimmen, mit dem der Cronjob selbst ausgeführt wird.
CpnCrunch

Stellen Sie beim Ausführen eines GUI-Prozesses mit cron voran export DISPLAY=:0, um Could not connect to displayFehler zu vermeiden . * * * * * export DISPLAY=:0 && pgrep processname > /dev/null || /path/to/processname -args0 -args1
Benjam

9

Führen Sie ein Skript anstelle des Programms aus. Es gibt viele Möglichkeiten. Beispielsweise :

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

1
Zu Ihrer Information: Die Verwendung skalarer Variablen zum Speichern von Argumentlisten wird als schlechte Praxis angesehen. Ein Beispiel für einen Fall, in dem dies fehlschlägt, finden Sie unter mywiki.wooledge.org/BashFAQ/050 .
Charles Duffy

... ähnlich pgrep myprog; if [ $? -ne 0 ]; then ...wäre besser geschrieben alsif ! pgrep myprog; then ...
Charles Duffy

... dieser letztere Stil ist nicht nur besser lesbar, sondern auch weniger fehleranfällig: Es ist leicht, den Wert von unbeabsichtigt zu stören $?, beispielsweise durch Hinzufügen von Protokollnachrichten oder Fehlerbehandlung zwischen Zeilen.
Charles Duffy

7

Dieses Skript wird nicht erneut ausgeführt, wenn die vorherige Instanz noch nicht abgeschlossen ist. Wenn Sie etwas nicht ausführen möchten, wenn ein anderer bestimmter Prozess ausgeführt wird, lesen Sie das Skript von 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

Sie könnten eine Sperrdatei in Ihrem Skript verwenden, siehe jedoch Prozessverwaltung .

flock ist ein Dienstprogramm, das verwendet werden kann.


gut! Jetzt kann die Synchronisierung über diese langsame Leitung die erforderliche Zeit in */5 * * * * root flock /run/shm rsync -auhx --numeric-ids -e "ssh -T -c arcfour128 -o Compression=no -x" [source] [user]@[host]:[dest]
Anspruch

1

Dies wird normalerweise vom Programm selbst und nicht von erledigt cron. Hierfür gibt es zwei Standardtechniken:

1) grepdie Ausgabe von, um pszu sehen, ob bereits ein Prozess mit diesem Namen ausgeführt wird

2) Überprüfen Sie beim Start zunächst, ob eine PID-Datei (Prozess-ID) vorhanden ist, normalerweise bei /var/run/program_name.pid, und lesen Sie, falls vorhanden, die PID aus der Datei aus und prüfen Sie, ob dieser Prozess noch vorhanden ist. Wenn dies der Fall ist, lehnen Sie den Start ab. Wenn die PID-Datei nicht vorhanden ist oder die PID in der Datei verschwunden ist, erstellen Sie eine PID-Datei, schreiben Sie Ihre Prozess-ID hinein und fahren Sie mit dem normalen Start fort.

Während es technisch möglich ist, Bash-Pipes zu schreiben, die beides direkt in Ihre Crontab ausführen, ist es besser, sie dem zu startenden Programm hinzuzufügen (damit sie unabhängig vom Start angewendet werden) oder ein Wrapper-Skript zu schreiben handhaben Sie dies, wie harrymc vorgeschlagen hat.


0

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

Ich habe die obige Antwort mit einer Verbesserung des Mustervergleichs wiederverwendet. pgrep ohne f-Option stimmt nicht mit dem Prozessmuster überein. Es gibt jedoch ein Problem bei der Verwendung der Option f. Mit der Option f ist die Shell, die den Cron erzeugt, immer übereinstimmend und gibt ihre PID zurück, daher wird der Prozess nie neu gestartet.

Das Hinzufügen eines [] um eines der Buchstabenmuster entspricht nur dem Prozess, und die PID der Cron-Shell wird nicht zurückgegeben.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.