it-swarm.com.de

Cron Jobs und zufällige Zeiten, innerhalb vorgegebener Stunden

Ich brauche die Fähigkeit, ein PHP 20-mal am Tag zu völlig zufälligen Zeiten auszuführen. Ich möchte auch, dass es nur zwischen 9.00 und 23.00 Uhr ausgeführt wird.

Ich bin mit dem Erstellen von Cronjobs unter Linux vertraut.

84
floatleft

Wenn ich verstehe, wonach Sie suchen, müssen Sie etwas Unordentliches tun, z. B. einen Cron-Job, in dem ein Bash-Skript ausgeführt wird, das die Laufzeiten nach dem Zufallsprinzip sortiert.

crontab:

0 9 * * * /path/to/bashscript

und in/path/to/bashscript:

#!/bin/bash

maxdelay=$((14*60))  # 14 hours from 9am to 11pm, converted to minutes
for ((i=1; i<=20; i++)); do
    delay=$(($RANDOM%maxdelay)) # pick an independent random delay for each of the 20 runs
    (sleep $((delay*60)); /path/to/phpscript.php) & # background a subshell to wait, then run the php script
done

Ein paar Anmerkungen: Bei diesem Ansatz werden die Ressourcen etwas verschwendet, da 20 Hintergrundprozesse um 9 Uhr morgens ausgelöst werden, von denen jeder auf eine zufällige Anzahl von Minuten wartet (bis zu 14 Stunden, dh 23 Uhr). Anschließend wird das PHP-Skript und gestartet Ausgänge. Da eine zufällige Anzahl von Minuten (nicht Sekunden) verwendet wird, sind die Startzeiten auch nicht so zufällig, wie sie sein könnten. Aber $ RANDOM steigt nur auf 32.767, und zwischen 9 und 23 Uhr gibt es 50.400 Sekunden. Es wäre etwas komplizierter, die Sekunden auch zufällig zu ordnen. Schließlich ist es möglich (aber nicht sehr wahrscheinlich), dass zwei oder mehr Instanzen des Skripts gleichzeitig gestartet werden, da die Startzeiten zufällig und unabhängig voneinander sind.

30
Gordon Davisson

Ja, ja, die Frage ist über ein Jahr alt, aber vielleicht kann ich noch etwas Nützliches hinzufügen:

Wie kann man zwischen 9 und 23 Uhr 20-mal am Tag etwas in zufälliger Reihenfolge basteln? Das ist bei cron ein bisschen knifflig, weil Sie 14 Stunden durch 20 Ausführungszeiten teilen. Die anderen Antworten gefallen mir nicht besonders, da sie das Schreiben eines Bash-Wrapper-Skripts für Ihr PHP-Skript erfordern.

Wenn Sie mir jedoch erlauben, die zeitliche und frequenzbezogene Beschränkung zwischen 8:30 Uhr und 23:09 Uhr auf 13 Mal zu lockern, ist dies möglicherweise der Trick, und dies alles innerhalb der Grenzen Ihrer Crontab:

30 8-21/* * * * sleep ${RANDOM:0:2}m ; /path/to/script.php

$ {RANDOM: 3: 2} verwendet bashs $ RANDOM, das andere bereits erwähnt haben, fügt jedoch das Bash-Array-Slicing hinzu. Da Bash-Variablen nicht typisiert sind, wird die 16-Bit-Zahl mit Pseudozufallsvorzeichen auf die ersten 2 ihrer 5 Dezimalstellen gekürzt, sodass Sie einen kurzen Einzeiler erhalten, um Ihren Cronjob zwischen 10 und 99 Minuten zu verzögern (obwohl die Verteilung auf voreingenommen ist) 10 bis 32).

Das Folgende könnte auch für Sie funktionieren, aber ich fand, dass es aus irgendeinem Grund "weniger zufällig" ist (vielleicht wird das Benfordsche Gesetz durch das Modulieren von Pseudozufallszahlen ausgelöst. Hey, ich weiß nicht, ich bin durchgefallen ... Schuld daran auf Bash!):

30 8-21/* * * * sleep $[RANDOM\%90]m ; /path/to/script.php

Sie müssen das Modul wie oben unter '\%' rendern, da cron (zumindest Linux 'vixie-cron') die Zeile beendet, wenn es auf ein nicht entkoppeltes '%' stößt.

Vielleicht könnten Sie die restlichen 7 Skriptausführungen erhalten, indem Sie eine weitere Zeile mit einem Bereich von weiteren 7 Stunden hinzufügen. Oder lockern Sie Ihre Einschränkung, um zwischen 3 Uhr morgens und 23 Uhr abends zu laufen.

119
al-x

Daher verwende ich Folgendes, um einen Befehl zwischen 1:00 und 330:00 Uhr auszuführen

0 1 * * * Perl -le 'sleep Rand 9000' && *command goes here*

Das hat sich um meine zufälligen Bedürfnisse gekümmert. Das sind 9000 Sekunden == 150 Minuten == 2,5 Stunden

53
Dave

Cron bietet eine Variable RANDOM_DELAY An. Siehe crontab(5) für Details.

Mit der Variablen RANDOM_DELAY können Jobstarts um eine zufällige Anzahl von Minuten verzögert werden, wobei die Obergrenze durch die Variable festgelegt wird.

Dies tritt häufig in anacron Jobs auf, kann aber auch in crontab nützlich sein.

Möglicherweise müssen Sie vorsichtig sein, wenn einige Jobs mit feiner (Minuten-) Granularität ausgeführt werden und andere grob sind.

17
Micah Elliott

Mein erster Gedanke wäre, einen Cron-Job zu erstellen, der 20 zufällig geplante Jobs startet. Das Dienstprogramm at (http://unixhelp.ed.ac.uk/CGI/man-cgi?at) wird zum Ausführen von Befehlen zu einem bestimmten Zeitpunkt verwendet.

6
klaus

Ich habe am Ende sleep $(( 1$(date +%N) % 60 )) ; dostuffs verwendet (kompatibel mit bash & sh)

Das Präfix 1 erzwingt die Interpretation von Datum +% N (z. B. 00551454) nach NICHT-Basis 8.

Vergessen Sie nicht,% mit \% in einer crontab-Datei zu entkommen

* * * * *  nobody  sleep $(( 1$(date +\%N) \% 60 )) ; dostuffs 
5
131

at -f [file] [timespec]

oder

echo [command] | at [timespec]

oder

at [timespec] ... und interaktive Angaben wie die Aufnahme von script.

Befehl

Bei Läufen muss der Text auf stdin oder in der mit -f [file] Angegebenen Datei angegeben werden.

Zeitangabe

Hier ist die [timespec] Grammatik . Es kann so etwas sein wie:

  • 24-Stunden-Zeit als 4-stellige Ganzzahl, z. 0100, 2359, 1620
  • now + 10 minutes
  • 2071-05-31 - 5 hours 12 minutes UTC

Wenn Sie die Zeitzone explizit angeben, erlaubt einige Versionen der Zeitspezifikation möglicherweise nur UTC für das optionale Zeitzonenargument.

Beispiel

cat script.sh | at now + $(($RANDOM % 10)) hours $(($RANDOM % 60)) minutes

at -f script.sh now + $(($RANDOM % 10)) hours $(($RANDOM % 60)) minutes

Versuch es...

Sie können das Parsing der Bash testen, indem Sie echo voranstellen und die Pipe | () Schließen.

echo cat script.sh \| at now + $(($RANDOM % 10)) hours $(($RANDOM % 60)) minutes

echo at -f script.sh now + $(($RANDOM % 10)) hours $(($RANDOM % 60)) minutes

Verwenden Sie atq und Auftragsinhalte (Umgebungsvariablen, Setup und Befehl/Skript) mit at -c [jobid], Um geplante Aufträge anzuzeigen.

Hinweis

Das System ist Teil von cron, und die interaktive Eingabeaufforderung erfasst tatsächlich den gesamten aktuellen Status Ihrer Shell, sodass Sie Befehle ausführen können, ohne absolute Pfade anzugeben.

1
mcint

die Lösung von al-x funktioniert bei mir nicht, da crontab-Befehle nicht in bash, sondern in sh ausgeführt werden. Was funktioniert ist:

30 8 * * * bash -c "sleep $[RANDOM\%90]m" ; /path/to/script.py
0
Wilbert

Für diejenigen, die den Weg hierher gegoogelt haben:

Wenn Sie anacron (Ubuntu Desktop und Laptop) verwenden, können Sie bearbeiten

/etc/anacrontab

und hinzufügen

RANDOM_DELAY=XX 

Wobei XX die Anzahl der Minuten ist, die Sie den Basisjob verzögern möchten.

Anacron ist wie cron, erwartet jedoch nicht, dass Ihr Computer (wie unsere Laptops) rund um die Uhr in Betrieb ist, und führt die Skripte aus, die er aufgrund eines Systemausfalls übersehen hat.

0
Ganesh Krishnan