Ich muss einen cron-Job durch ein Skript hinzufügen, das ich zum Einrichten eines Servers ausführt. Ich verwende derzeit Ubuntu. Ich kann crontab -e
verwenden, aber dies öffnet einen Editor, um die aktuelle Crontab zu bearbeiten. Ich möchte das programmgesteuert machen.
Ist das möglich?
Cron-Jobs werden normalerweise in einer Benutzerdatei unter /var/spool/cron
gespeichert.
Am einfachsten ist es, wenn Sie einfach eine Textdatei mit dem konfigurierten Job erstellen und diese dann in den cron-Spool-Ordner kopieren und sicherstellen, dass er die richtigen Berechtigungen hat.
Hier ist ein Einzeiler, der den neuen Job nicht in einer Datei benötigt/benötigt:
(crontab -l 2>/dev/null; echo "*/5 * * * * /path/to/job -with args") | crontab -
Der 2>/dev/null
ist wichtig, damit Sie nicht die no crontab for username
-Nachricht erhalten, die einige * Nixe erzeugen, wenn derzeit keine Crontab-Einträge vorhanden sind.
Für Benutzer-Crontabs (einschließlich root) können Sie Folgendes tun:
crontab -l -u user | cat - filename | crontab -u user -
die Datei "Dateiname" enthält Elemente, die angehängt werden sollen. Sie können die Textbearbeitung auch mit sed
oder einem anderen Werkzeug anstelle von cat
durchführen. Sie sollten den Befehl crontab
verwenden, anstatt die Datei direkt zu ändern.
Eine ähnliche Operation wäre:
{ crontab -l -u user; echo 'crontab spec'; } | crontab -u user -
Wenn Sie System-Crontabs ändern oder erstellen, können diese wie normale Textdateien bearbeitet werden. Sie werden in den Verzeichnissen /etc/cron.d
, /etc/cron.hourly
, /etc/cron.daily
, /etc/cron.weekly
, /etc/cron.monthly
und in den Dateien /etc/crontab
und /etc/anacrontab
gespeichert.
In Ubuntu und vielen anderen Distributionen können Sie einfach eine Datei in das Verzeichnis /etc/cron.d
ablegen, das eine einzige Zeile mit einem gültigen Eintrag crontab enthält. Sie müssen einer vorhandenen Datei keine Zeile hinzufügen.
Wenn Sie täglich etwas benötigen, fügen Sie einfach eine Datei in /etc/cron.daily
ein. Ebenso können Sie Dateien in /etc/cron.hourly
, /etc/cron.monthly
und /etc/cron.weekly
ablegen.
Crontab-Dateien sind einfach Textdateien und können daher wie jede andere Textdatei behandelt werden. Der Befehl crontab
soll die Bearbeitung von Crontab-Dateien sicherer machen. Bei der Bearbeitung mit diesem Befehl wird die Datei auf Fehler geprüft und nur dann gespeichert, wenn keine vorhanden ist.
Mit crontab [path to file]
kann eine in einer Datei gespeicherte Crontab angegeben werden. Wie crontab -e
wird die Datei nur installiert, wenn sie fehlerfrei ist.
Daher kann ein Skript entweder Cron-Tab-Dateien direkt schreiben oder in eine temporäre Datei schreiben und sie mit dem Befehl crontab [path to temp file]
laden. Direktes Schreiben erspart das Schreiben einer temporären Datei, vermeidet jedoch auch die Sicherheitsüberprüfung.
Eine noch einfachere Antwort auf Ihre Frage wäre:
echo "0 1 * * * /root/test.sh" | tee -a /var/spool/cron/root
Sie können Cronjobs auf Remote-Servern wie folgt einrichten:
#!/bin/bash
servers="srv1 srv2 srv3 srv4 srv5"
for i in $servers
do
echo "0 1 * * * /root/test.sh" | ssh $i " tee -a /var/spool/cron/root"
done
In Linux ist der Standardspeicherort der crontab
-Datei /var/spool/cron/
. Hier finden Sie die crontab
-Dateien aller Benutzer. Sie müssen lediglich Ihren Cronjob-Eintrag an die Datei des jeweiligen Benutzers anhängen. Im obigen Beispiel wird die Crontab-Datei des Stammbenutzers mit einem Cronjob angehängt, um jeden Tag um 1 Uhr /root/test.sh
auszuführen.
Als Korrektur für diejenigen, die crontab -l | crontab -
vorschlagen: Dies funktioniert nicht auf jedem System. Zum Beispiel musste ich einen Job zur Root-Crontab auf Dutzenden von Servern hinzufügen, auf denen eine alte SUSE-Version ausgeführt wird (fragen Sie nicht nach dem Grund). Alte SUSEs fügen der Ausgabe von crontab -l
Kommentarzeilen hinzu, wodurch crontab -l | crontab -
nicht idempotent wird (Debian erkennt dieses Problem in der crontab-Manpage und hat ihre Version von Vixie Cron gepatcht, um das Standardverhalten von crontab -l
zu ändern).
Um Crontabs programmgesteuert auf Systemen zu bearbeiten, auf denen crontab -l
Kommentare hinzufügt, können Sie Folgendes versuchen:
EDITOR=cat crontab -e > old_crontab; cat old_crontab new_job | crontab -
EDITOR=cat
weist crontab an, cat
als Editor zu verwenden (nicht die übliche Standardeinstellung vi). Dadurch wird die Datei nicht geändert, sondern in stdout kopiert. Dies kann immer noch fehlschlagen, wenn crontab -
Eingaben in einem anderen Format erwartet als crontab -e
. Versuchen Sie nicht, den endgültigen crontab -
durch crontab -e
zu ersetzen - er funktioniert nicht.
Nun, /etc/crontab
ist nur eine ASCII-Datei, also ist es am einfachsten
echo "*/15 * * * * root date" >> /etc/crontab
dadurch wird ein Job hinzugefügt, der Sie alle 15 Minuten per E-Mail benachrichtigt. Passen Sie den Geschmack an und testen Sie mit grep
oder auf andere Weise, ob die Zeile bereits hinzugefügt wurde, um Ihr Skript idempotent zu machen.
Unter Ubuntu und anderen können Sie auch Dateien in /etc/cron.*
ablegen, was einfacher ist, um zu testen und auf --- zu testen. Außerdem machen Sie sich keine (System-) Konfigurationsdateien wie /etc/crontab
zu schaffen.
So ändern Sie Cron einen Eintrag, ohne die Cron-Datei direkt zu bearbeiten (was verpönt ist).
crontab -l -u <user> | sed 's/find/replace/g' | crontab -u <user> -
Wenn Sie einen Cron-Eintrag entfernen möchten, verwenden Sie Folgendes:
crontab -l -u <user> | sed '/find/d' | crontab -u <user> -
Mir ist klar, dass dies nicht das ist, wonach Gaurav gefragt hat, aber warum haben nicht alle Lösungen an einem Ort?
Ich habe ein Crontab-Deployment-Tool in Python geschrieben: https://github.com/monklof/deploycron
pip install deploycron
Die Installation Ihrer Crontab ist sehr einfach. Dadurch wird die Crontab in die vorhandene Crontab des Systems integriert.
from deploycron import deploycron
deploycron(content="* * * * * echo hello > /tmp/hello")
(Ich habe nicht genug Reputation, um etwas zu kommentieren, also füge ich als Antwort hinzu: Sie können es gerne als Kommentar neben seiner Antwort hinzufügen.)
Joe Casadontes Einzeiler ist perfekt, außer wenn Sie mit set -e
laufen, d. H. Wenn Ihr Skript bei einem Fehler als fehlgeschlagen eingestellt ist und noch keine Cronjobs vorhanden sind. In diesem Fall erstellt der Einzeiler NICHT den Cronjob, stoppt das Skript jedoch NICHT. Der stille Ausfall kann sehr irreführend sein.
Der Grund ist, dass crontab -l
mit einem 1
-Rückkehrcode zurückgegeben wird, wodurch der nachfolgende Befehl (die echo
) nicht ausgeführt wird ... daher wird der Cronjob nicht erstellt. Da sie jedoch aufgrund der Klammern als Unterprozess ausgeführt werden, stoppen sie das Skript nicht.
(Wenn Sie den gleichen Befehl erneut ausführen, funktioniert dies: Wenn Sie einmal crontab -
ausgeführt haben, gibt crontab -l
immer noch nichts aus, aber es wird kein Fehler mehr ausgegeben (Sie erhalten keine no crontab for <user>
-Nachricht mehr) nachfolgende echo
wird ausgeführt und die crontab erstellt
Wenn Sie mit set -e
laufen, muss die Zeile auf jeden Fall Folgendes sein:
(crontab -l 2>/dev/null || true; echo "*/5 * * * * /path/to/job -with args") | crontab -
Es ist ein Ansatz, den Cron-Job schrittweise hinzuzufügen:
ssh [email protected]$PRODUCT_IP Nohup "echo '*/2 * * * * ping -c2 PRODUCT_NAME.com >> /var/www/html/test.html' | crontab -u USER_NAME -"