it-swarm.com.de

Wie erstelle ich eine Crontab durch ein Skript?

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?

105
gaurav

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.

10
Jason Stelzer

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.

272
Joe Casadonte

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.

49

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.

25
IvanGoneKrazy

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.

15
cledoux

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.

12
ganesh pathak

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.

3
user2845840

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.

2

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?

1
Brian Smith

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")
1
monklof

(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 -
0
Faria

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 -"
0