Sie haben */30
in der Minutenangabe - das heißt jede Minute, aber mit einem Schritt von 30 (mit anderen Worten, jede halbe Stunde). Da cron
es sich nicht um Auflösungen von weniger als einer Minute handelt, müssen Sie einen anderen Weg finden.
Eine Möglichkeit, obwohl es ein bisschen kludge (a) ist , besteht darin, zwei Jobs zu haben, von denen einer um 30 Sekunden versetzt ist:
# Need these to run on 30-sec boundaries, keep commands in sync.
* * * * * /path/to/executable param1 param2
* * * * * ( sleep 30 ; /path/to/executable param1 param2 )
Sie werden sehen, dass ich Kommentare hinzugefügt und formatiert habe, um sicherzustellen, dass sie einfach synchronisiert werden können.
Beide cron
Jobs werden tatsächlich jede Minute ausgeführt, aber der letztere wartet eine halbe Minute, bevor er das "Fleisch" des Jobs ausführt /path/to/executable
.
Weitere (nicht cron
basierte) Optionen finden Sie in den anderen Antworten hier, insbesondere in den Erwähnungen fcron
und systemd
. Diese sind wahrscheinlich vorzuziehen, vorausgesetzt, Ihr System kann sie verwenden (z. B. Installation fcron
oder Installation einer Distribution systemd
).
Wenn Sie die kludgy-Lösung nicht verwenden möchten, können Sie eine schleifenbasierte Lösung mit einer kleinen Änderung verwenden. Sie müssen immer noch verwalten, dass Ihr Prozess in irgendeiner Form ausgeführt wird, aber sobald dies sortiert ist, sollte das folgende Skript funktionieren:
#!/bin/env bash
# Debug code to start on minute boundary and to
# gradually increase maximum payload duration to
# see what happens when the payload exceeds 30 seconds.
((maxtime = 20))
while [[ "$(date +%S)" != "00" ]]; do true; done
while true; do
# Start a background timer BEFORE the payload runs.
sleep 30 &
# Execute the payload, some random duration up to the limit.
# Extra blank line if excess payload.
((delay = RANDOM % maxtime + 1))
((maxtime += 1))
echo "$(date) Sleeping for ${delay} seconds (max ${maxtime})."
[[ ${delay} -gt 30 ]] && echo
sleep ${delay}
# Wait for timer to finish before next cycle.
wait
done
Der Trick besteht darin, ein sleep 30
Aber zu verwenden, um es im Hintergrund zu starten, bevor Ihre Nutzdaten ausgeführt werden. Warten Sie nach Abschluss der Nutzdaten einfach, bis der Hintergrund sleep
fertig ist.
Wenn die Nutzlast n
Sekunden dauert (wo n <= 30
), beträgt die Wartezeit nach der Nutzlast 30 - n
Sekunden. Wenn es länger als 30 Sekunden dauert, wird der nächste Zyklus verzögert, bis die Nutzlast fertig ist, jedoch nicht mehr.
Sie werden sehen, dass ich dort Debug-Code habe, der an einer Minute beginnt, damit die Ausgabe zunächst leichter zu verfolgen ist. Ich erhöhe auch schrittweise die maximale Nutzlastzeit, damit die Nutzlast möglicherweise die 30-Sekunden-Zykluszeit überschreitet (eine zusätzliche Leerzeile wird ausgegeben, damit der Effekt offensichtlich ist).
Es folgt ein Probelauf (wobei die Zyklen normalerweise 30 Sekunden nach dem vorherigen Zyklus beginnen):
Tue May 26 20:56:00 AWST 2020 Sleeping for 9 seconds (max 21).
Tue May 26 20:56:30 AWST 2020 Sleeping for 19 seconds (max 22).
Tue May 26 20:57:00 AWST 2020 Sleeping for 9 seconds (max 23).
Tue May 26 20:57:30 AWST 2020 Sleeping for 7 seconds (max 24).
Tue May 26 20:58:00 AWST 2020 Sleeping for 2 seconds (max 25).
Tue May 26 20:58:30 AWST 2020 Sleeping for 8 seconds (max 26).
Tue May 26 20:59:00 AWST 2020 Sleeping for 20 seconds (max 27).
Tue May 26 20:59:30 AWST 2020 Sleeping for 25 seconds (max 28).
Tue May 26 21:00:00 AWST 2020 Sleeping for 5 seconds (max 29).
Tue May 26 21:00:30 AWST 2020 Sleeping for 6 seconds (max 30).
Tue May 26 21:01:00 AWST 2020 Sleeping for 27 seconds (max 31).
Tue May 26 21:01:30 AWST 2020 Sleeping for 25 seconds (max 32).
Tue May 26 21:02:00 AWST 2020 Sleeping for 15 seconds (max 33).
Tue May 26 21:02:30 AWST 2020 Sleeping for 10 seconds (max 34).
Tue May 26 21:03:00 AWST 2020 Sleeping for 5 seconds (max 35).
Tue May 26 21:03:30 AWST 2020 Sleeping for 35 seconds (max 36).
Tue May 26 21:04:05 AWST 2020 Sleeping for 2 seconds (max 37).
Tue May 26 21:04:35 AWST 2020 Sleeping for 20 seconds (max 38).
Tue May 26 21:05:05 AWST 2020 Sleeping for 22 seconds (max 39).
Tue May 26 21:05:35 AWST 2020 Sleeping for 18 seconds (max 40).
Tue May 26 21:06:05 AWST 2020 Sleeping for 33 seconds (max 41).
Tue May 26 21:06:38 AWST 2020 Sleeping for 31 seconds (max 42).
Tue May 26 21:07:09 AWST 2020 Sleeping for 6 seconds (max 43).
Wenn Sie die klobige Lösung vermeiden möchten, ist dies wahrscheinlich besser. Sie benötigen noch einen cron
Job (oder einen gleichwertigen Job), um regelmäßig zu erkennen, ob dieses Skript ausgeführt wird, und wenn nicht, starten Sie es. Das Skript selbst übernimmt dann das Timing.
(a) Einige meiner Arbeitskollegen würden sagen, dass Kludges meine Spezialität sind :-)