Wenn Sie wirklich nicht cron (oder bei) Sie nur einen einfachen Bash-Skript verwenden können, mögen:
#!/bin/bash
while true
do
#Do something
echo Invoke long-running node.js script
#Wait an hour
sleep 3600
done
Der (offensichtliche) Nachteil ist, dass Sie es irgendwie im Hintergrund laufen lassen müssen (zB über nohup oder Bildschirm) und fügen Sie eine ordnungsgemäße Fehlerbehandlung hinzu (wobei Sie s cript kann fehlschlagen, und Sie möchten immer noch, dass es in einer Stunde wieder läuft).
Etwas aufwändigere "benutzerdefinierten Skript" Lösung könnte so sein:
#!/bin/bash
#Settings
LAST_RUN_FILE=/var/run/lock/hourly.timestamp
FLOCK_LOCK_FILE=/var/run/lock/hourly.lock
FLOCK_FD=100
#Minimum time to wait between two job runs
MIN_DELAY=3600
#Welcome message, parameter check
if [ -z $1 ]
then
echo "Please specify the command (job) to run, as follows:"
echo "./hourly COMMAND"
exit 1
fi
echo "[$(date)] MIN_DELAY=$MIN_DELAY seconds, [email protected]"
#Set an exclusive lock, or skip execution if it is already set
eval "exec $FLOCK_FD>$FLOCK_LOCK_FILE"
if ! flock -n $FLOCK_FD
then
echo "Lock is already set, skipping execution."
exit 0
fi
#Last run timestamp
if ! [ -e $LAST_RUN_FILE ]
then
echo "Timestamp file ($LAST_RUN_FILE) is missing, creating a new one."
echo 0 >$LAST_RUN_FILE
fi
#Compute delay, and wait
let DELAY="$MIN_DELAY-($(date +%s)-$(cat $LAST_RUN_FILE))"
if [ $DELAY -gt 0 ]
then
echo "Waiting for $DELAY seconds, before proceeding..."
sleep $DELAY
fi
#Proceed with an actual task
echo "[$(date)] Running the task..."
echo
"[email protected]"
#Update the last run timestamp
echo
echo "Done, going to update the last run timestamp now."
date +%s >$LAST_RUN_FILE
Dieses 2 Dinge tun:
eine exklusive Ausführung Schloss Set (mit Herde), so dass keine zwei Instanzen des Jobs zur gleichen Zeit ausgeführt werden, unabhängig davon, wie Sie sie starten (manuell oder über cron usw.);
Wenn der letzte Auftrag abgeschlossen wurde weniger als MIN_DELAY Sekunden vor, es für die verbleibende Zeit schlafen, bevor die Arbeit wieder zum Laufen;
Nun, wenn Sie dieses Skript planen zu laufen, sagen alle 15 Minuten mit cron, wie folgt aus:
* * * * * /home/myuser/hourly my_periodic_task and it's arguments
Es wird garantiert mit der festen Verzögerung von mindestens auszuführen MIN_DELAY (eine Stunde) seit dem letzten abgeschlossenen Auftrag, und Zwischenläufe werden übersprungen.
Im schlimmsten Fall wird es in MIN_DELAY + 15 Minuten (wie die Planungsperiode ist diskret), aber nie früher als ausführen.
Andere nicht-cron Scheduling-Verfahren sollten auch funktionieren (d.h. nur das Skript in einer Schleife ausgeführt wird, oder Neuplanung und jeden Durchlauf mit bei).
Verwenden Sie Cron in Kombination mit Dateisystemsperrung. Der Prozess prüft, ob eine Sperrdatei bereits existiert. Wenn dies der Fall ist, wird es beendet, wenn nicht, erstellt es eine und startet dann seine Verarbeitungsaufgabe. Wenn Sie fertig sind, wird die Sperrdatei wieder entfernt. Zusätzliche Punkte der Sperrdatei enthalten die Prozess-ID des Prozesses, der sie erstellt hat. Dies ermöglicht einen Bereinigungsjob, um abgestürzte Jobs zu entfernen. – arkascha
Sie können cron + flock verwenden: siehe http://serverfault.com/questions/82857/prevent-duplicate-cron-jobs-running – zeppelin
Verwenden Sie 'at' am Ende Ihres Skripts, um den nächsten Lauf zu planen. – Eric