Sie haben */30
im Minuten Das heißt, jede Minute, aber mit einer Schrittweite von 30 (mit anderen Worten, jede halbe Stunde). Da cron
nicht auf subminütige Auflösungen heruntergeht, müssen Sie einen anderen Weg finden.
Eine Möglichkeit, auch wenn sie ein wenig umständlich ist (a) ist es, zwei Aufträge zu haben, einer davon um 30 Sekunden versetzt:
# 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, damit sie leicht synchronisiert werden können.
Beide cron
Aufträge laufen eigentlich jede Minute, aber die letztere wartet man eine halbe Minute, bevor man den "Hauptteil" des Auftrags ausführt, /path/to/executable
.
Für andere (nicht cron
-basierten) Optionen, siehe die anderen Antworten hier, insbesondere die, die sich auf fcron
y systemd
. Diese sind wahrscheinlich vorzuziehen, vorausgesetzt, Ihr System ist in der Lage, sie zu verwenden (z. B. durch die Installation von fcron
oder eine Distro mit systemd
in ihr).
Wenn Sie nicht verwenden möchten, können Sie eine schleifenbasierte Lösung mit einer kleinen Änderung verwenden. Sie müssen sich immer noch darum kümmern, dass Ihr Prozess in irgendeiner Form weiterläuft, aber wenn das erledigt 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 in der Verwendung eines sleep 30
aber um es in der Hintergrund bevor Ihre Nutzlast ausgeführt wird. Nachdem die Nutzlast beendet ist, warten Sie einfach auf die Hintergrund sleep
zu beenden.
Wenn die Nutzlast n
Sekunden (wobei n <= 30
), die Wartezeit nach der Nutzlast beträgt dann 30 - n
Sekunden. Wenn es dauert mehr mehr als 30 Sekunden, so wird der nächste Zyklus so lange verzögert, bis die Nutzlast beendet ist, jedoch nicht länger.
Sie werden sehen, dass ich einen Debug-Code eingefügt habe, der an der Grenze von einer Minute beginnt, damit die Ausgabe anfangs leichter zu verfolgen ist. Außerdem erhöhe ich allmählich die maximale Nutzlastzeit, so dass Sie schließlich sehen, dass die Nutzlast 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 plumpe Lösung vermeiden wollen, ist dies wahrscheinlich besser. Sie brauchen immer noch eine cron
Job (oder ein gleichwertiges Programm), um in regelmäßigen Abständen festzustellen, ob dieses Skript läuft, und wenn nicht, es zu starten. Das Skript selbst kümmert sich dann um das Timing.
(a) Einige meiner Arbeitskollegen würden sagen, dass Schlampereien meine Spezialität sind :-)