Vorweg:
Für Individuelle Probleme oder Problemlösungen usw bitte einen eigenen Thread erstellen, aber euer Problem nicht in den Anleitungs-Threads behandeln, sonst werden diese sehr schnell sehr unübersichtlich und keiner hat mehr Lust sich Seitenweise eigentlich belangloses Zeug (nichts was mit der Anleitung zu tun hat) durchzulesen.
Danke
Der Cron-Daemon dient der zeitbasierten Ausführung von Prozessen in Unix und unixartigen Betriebssystemen wie Linux, BSD oder Mac OS X, um wiederkehrende Aufgaben – sogenannte Cronjobs – zu automatisieren.
Die auszuführenden Anweisungen werden in einer benutzereigenen Tabelle gespeichert, der sogenannten Crontab. Der Begriff leitet sich ab von griechisch chronos = die Zeit und lat. tabula = die Tafel oder das Brett und bedeutet demnach so viel wie „Zeittafel“ (also „Stundenplan“).
Diese Tabelle besteht aus sechs Spalten; die ersten fünf dienen der Zeitangabe (Minute, Stunde, Tag, Monat, Wochentag), alle weiteren Zeichen bis zum Zeilenumbruch werden als der auszuführende Befehl aufgefasst.
Jedes Mal, wenn ein spezifischer Zeitpunkt erreicht wird, wird der entsprechende Befehl, meist ein Shellskript, ausgeführt.
Es gibt 2 Arten von crontabs die es zu unterscheiden gilt:
- Benutzer-Crontab -> Kann über den Konsolen Befehl crontab -e bearbeitet werden
- System-Crontab -> Datei /etc/crontab
gehört dem System und sollte von - egal welchen - Benutzern nicht geändert werden!
Die System-Crontab hat eine Spalte mehr als die Benutzer-Crontab, nämlich mit dem Benutzer der den Befehl oder Script ausführen soll
Wie auch bei Scripts üblich werden auch die crontabs von oben nach unten abgearbeitet, ist aber eine Zeile fehlerhaft wird alles dadrunter nicht mehr ausgeführt - also am besten eure eigenen Einträge ans Ende paken. Wichtig ist aber das ihr nach eurer Zeile <Enter> drückt also ein Zeilenumbruch habt!
Standardmässig wird die Crontab mit vi geöffnet. Wer stattdessen lieber nano nutzen möchte gibt ein mal folgenden Befehl ein: export EDITOR=nano
Ein Crontab-File besteht aus 6 "Spalten" pro Zeile:
1 - Minute (0-59)
2 - Stunde (0-23)
3 - Tag des Monats (1-31)
4 - Monat des Jahres (1-12)
5 - Wochentag (0-7, Sonntag ist 0 und 7)
6 - Absoluter Pfad zum Befehl/Script
Zur Verdeutlichung:
* * * * * Befehl der ausgeführt werden soll
- - - - -
| | | | |
| | | | +----- Wochentag (0 - 7) (Sonntag ist 0 und 7)
| | | +------- Monat (1 - 12)
| | +--------- Tag (1 - 31)
| +----------- Stunde (0 - 23)
+------------- Minute (0 - 59)
Eine Ausnahme bildet allerdings wie bereits erwähnt die /etc/crontab Datei! Da gibt es eine Spalte mehr um anzugeben wer den Befehl oder das Script ausführen soll:
1 - Minute (0-59)
2 - Stunde (0-23)
3 - Tag des Monats (1-31)
4 - Monat des Jahres (1-12)
5 - Tag der Woche (0-6, 0 ist Sonntag)
6 - Auszuführender Benutzer
7 - Absoluter Pfad zum Befehl/Script
Benutzer-Crontab Beispiele: (crontab -e)
Spoiler anzeigen
Wenn ein Script/Befehl bei System Start ausgeführt werden soll:
Wenn ein Script/Befehl jede Minute, jede Stunde, jeden Tag usw ausgeführt werden soll:
(also um 12:00 , 12:01 , 12:02 , 12:03 usw)
Wenn ein Script/Befehl um 10 nach von jeder Stunde, jeden Tag usw ausgeführt werden soll:
(also um 12:10 , 13:10 , 14:10 usw)
Wenn ein Script/Befehl zu bestimmten Minuten, jede Stunde, jeden Tag usw ausgeführt werden soll:
(also um 12:10 , 12:30 , 12:50, 13:10 usw)
Wenn ein Script/Befehl alle 2 Minuten, jede Stunde, jeden Tag usw ausgeführt werden soll:
(also um 12:02 , 12:04 , 12:06 usw)
Wenn ein Script/Befehl alle 10 Minuten, jede Stunde, jeden Tag usw ausgeführt werden soll:
(also um 12:10 , 12:20 , 12:30 usw)
Wenn ein Script/Befehl jede Woche Montag morgends um 6 Uhr ausgeführt werden soll:
Wenn ein Script/Befehl nur in einem bestimmten Monat ausgeführt werden soll, vom 1. bis 23. Dezember morgends um 06:00:
System-Crontab Beispiele: (/etc/crontab)
Spoiler anzeigen
Wenn ein Script/Befehl bei System Start ausgeführt werden soll:
Wenn ein Script/Befehl jede Minute, jede Stunde, jeden Tag usw ausgeführt werden soll:
(also um 12:00 , 12:01 , 12:02 , 12:03 usw)
Wenn ein Script/Befehl um 10 nach von jede Stunde, jeden Tag usw ausgeführt werden soll:
(also um 12:10 , 13:10 , 14:10 usw)
Wenn ein Script/Befehl zu bestimmten Minuten, jede Stunde, jeden Tag usw ausgeführt werden soll:
(also um 12:10 , 12:30 , 12:50, 13:10 usw)
Wenn ein Script/Befehl alle 2 Minuten, jede Stunde, jeden Tag usw ausgeführt werden soll:
(also um 12:02 , 12:04 , 12:06 usw)
Wenn ein Script/Befehl alle 10 Minuten, jede Stunde, jeden Tag usw ausgeführt werden soll:
(also um 12:10 , 12:20 , 12:30 usw)
Wenn ein Script/Befehl jede Woche Montag morgends um 6 Uhr ausgeführt werden soll:
Wenn ein Script/Befehl nur in einem bestimmten Monat ausgeführt werden soll, vom 1. bis 23. Dezember morgends um 06:00:
Es gibt auch noch weitere Crontab-untypische Einstellungsmöglichkeiten wie @reboot
Genaueres dazu kann man dort nachlesen: http://wiki.ubuntuusers.de/Cron#Cronjobs-manuell-einrichten
(etwas runter scrollen bis zur Tabelle "String, Bedeutung, cron-Schreibweise")
Wichtig ist auch das ihr nicht Systemdateien überschreibt! Also nicht daher gehen und /etc/crontab oder /etc/rc.local usw mit unter Windows bearbeiteten Dateien überschreiben! Dabei gehen Dateirechte usw verloren!
Anmerkungen:
Unter Raspbmc wird der Cron Dienst standardmässig leider nicht automatisch ausgeführt!
Dafür gibt es 2 verschiedene Wege cron zu aktivieren:
- In der Raspbmc GUI unter Programs -> Raspbmc Settings -> System Configuration -> Service Management -> Cronjob Scheduler
- Über SSH die Datei /home/pi/.xbmc/userdata/addon_data/script.raspbmc.settings/settings.xml bearbeiten und die Einstellung sys.service.cron auf “true” stellen.
Wenn ein Script oder Befehl eine Ausgabe erzeugt (zB durch echo's) wäre es zudem ratsam die Ausgabe in den Mülleimer umzuleiten. Das erreicht man indem man hinter den Befehl/Script folgendes anhängt:
Erklärung:
Alle Befehle und Programme, welche in der Bash gestartet werden, erhalten drei Kanäle zugewiesen:
- Den Standardeingabekanal stdin, dieser hat die Nummer 0 (null). Normalerweise liest stdin Eingaben von der Tastatur, welche mit dem Terminal verbunden ist.
- Den Standardausgabekanal stdout, dieser hat die Nummer 1 (eins). Normalerweise schreibt stdout Ausgaben auf den Bildschirm, welcher mit dem Terminal verbunden ist.
- Den Standardfehlerkanal stderr, dieser hat die Nummer 2 (zwei). Normalerweise schreibt stderr Ausgaben auf den Bildschirm, welcher mit dem Terminal verbunden ist.
Die erste Umleitung " >/dev/null " schickt die StandardAusgabe (stdout) nach /dev/null, also dem klassischen Mülleimer von Linux
Das dahinter " 2>&1 " leitet Fehlermeldungen (stderr) auf den Kanal der StandardAusgabe (stdout) um und landet somit ebenfalls im Mülleimer
Dadurch vermeidet man möglicherweise zu viele Logeinträge in /var/log/syslog
Trotzdem werden schwerwiegende Fehler noch ins /var/log/syslog geschrieben und dort sollte auch der erste Ort sein wo ihr nachguckt wieso/weshalb/warum ein Befehl/Script über crontab nicht funktionieren will
Wichtig ist aber das generell keine Ausgabe auf eure Konsole erfolgt! Wenn ihr also ein Script über crontab starten lasst, welches eine Ausgabe erzeugt und ihr sehen wollt, dann müsst ihr eine Umleitung in eine Datei verwenden!
Erklärung:
Die doppelte Umleitung " >> " steht fürs sog. append, also danach einfügen. Dadurch wird der Inhalt der Datei nicht bei jedem ausführen überschrieben sondern ans Ende eingefügt. Wohin ihr das schreiben lasst ist relativ egal, allerdings kann es je nach Umfang der Ausgabe eine Mehrbelastung für eure SD bedeuten und dessen Haltbarkeit reduzieren... Um das zu verhindern siehe > hier <
Das dahinter " 2>&1 " macht wieder das selbe wie oben erklärt: Fehlermeldungen werden ebenfalls in die Datei umgeleitet.
Ausserdem solltet ihr in euren Scripts immer mit Exit-Codes arbeiten damit das System bzw crontab auch weiss ob das Script erfolgreich oder fehlerhaft ausgeführt wurde.
Wenn alles in Ordnung ist nutzt man "exit 0", das sollte immer am Ende des Scripts stehen.
Wenn es Fehler gibt zB falsche Anforderungen die fürs Durchlaufen des Scripts erfüllt sein müssten oder weil en Befehl im Script einen Fehler verursacht hat, nutzt man alles über 0 also "exit 1" oder "exit 2" usw. Mehr zu den Exit-Codes könnt ihr hier nachlesen:
Spoiler anzeigen
Allgemein zu Scripts:
Scripts sollten immer so aufgebaut sein das in der ersten Zeile der Interpreter (shebang) angegeben wird und in der letzten Zeile ein ' exit 0 ' steht damit anderen Scripts/Programmen ein positiver Rückgabewert gegeben werden kann ala "script wurde erfolgreich ausgeführt und beendet"
Also so:
Der Interpreter ist wichtig damit das Programm gewählt werden kann der den nachfolgenden Code verarbeiten soll bzw kann
Interpreter:
Ein Skript kann von unterschiedlichen Interpretern interpretiert werden - oder auch nicht.
Es gibt einen POSIX-Standard, den die populären Shells alle ganz gut beherrschen. Was darüber hinaus geht kann die eine Shell aber die andere nicht, und die andere kann jenes, was erstere nicht kann oder anders löst.
Wenn man einen Interpreter ausdrücklich aufruft (bash /path/to/script.sh), dann wird dieser verwendet - ohne wenn und aber; der Shebang schaut in die Röhre, wird also ignoriert.
Natürlich kann man nicht erzwingen, dass das Skript in einem Interpreter funktionieren wird, für den es nicht geschrieben wurde. Das Skript wird ja nicht auf magische Weise umgeschrieben..
Der Aufruf:
Wenn man den Interpreter explizit aufruft, also beispielsweise
dann muss man zuvor das Skript nicht ausführbar machen, weil man den Interpreter ausführt und das Skript dessen Eingabedatei ist, so wie zB ein Bild die Eingabe für ein Grafikprogramm wie Gimp ist.
Lässt man den Interpreter weg, muss man das Skript erst ausführbar machen; dann wird der Shebang ausgewertet, der in der ersten Zeile steht und aus einem Kommentarzeichen
(engl.: sharp) besteht, dem
(engl.: bang) und dem Pfad zum Interpreter - üblicherweise dem absoluten Pfad, also /bin/bash oder /bin/sh
insgesamt also:
- Bei Skripten mit Shebang werden vom Linuxkernel die SUID- und SGID-Flags ignoriert.
- Mittels Shebang kann man ein Skript aufrufen, welches seinerseits wieder einen Shebang hat usw. Allerdings nur vier Rekursionstiefen tief, dann ist Schluss.
- Der Shebang kann um Parameter erweitert werden:
- Skripte in anderen Sprachen wie Lua, Python, Ruby usw. lassen sich analog mit einem Shebang starten - sofern das # dort als Kommentar toleriert wird, also
oder - Bei Skripten, bei denen man nicht weiß, auf welcher Linux-Plattform sie landen werden, findet man auch einen zweistufigen Aufruf, weil man beispielsweise nicht weiß, wo Lua installiert ist. Man ruft dann
auf, und verlässt sich darauf, dass env einheitlich installiert ist, und damit lua im Pfad gefunden wird.
Faustregeln
Soweit nicht anders verordnet, nimmt man
als erste Zeile des Skripts.
- Was mit der
klappt und mit
, das klappt fast immer auch mit der
- umgekehrt aber nicht! - Die
ist weit verbreitet und kommt auch bei Raspbian als interaktive Shell zum Einsatz. - Die
ist viel mächtiger als
. Die Zeit, die man beim Schreiben spart holt die schnellere Startzeit der sh niemals rein - außer man arbeitet in einer Umgebung, die es dringend gebietet mehr als Faustregeln zu lernen. - Die zsh ist auch sehr mächtig, aber Leute, die zsh-Tipps geben, wissen, dass kaum jemand die
nutzt. Deswegen schreiben sie dann auch ausdrücklich dazu, dass es zsh-Code ist.
Bekannte Probleme:
Da leider immer wieder Threads erstellt werden in denen die selben Problemchen behandelt werden, hier eine grobe Zusammenfassung der häufigsten Fehler im Umgang mit der crontab:
Wichtig ist:
- Der Benutzer der crontab hat das Recht die Datei auszuführen. Jeder Benutzer hat seine eigene crontab.
- Zum Script und innerhalb des Scripts absolute Pfade verwenden. Ein Absoluter Pfad beginnt mit dem Wurzelverzeichnis " / ". Absolut: /usr/local/smarthome/scripts/SQLBackup.py Relativ: SQLBackup.py. Werden im Script irgendwelche Dateien geöffnet oder geschrieben müssen dafür ebenfalls Absolute Pfade gesetzt sein.
- Wenn die gleiche Zeile (abgesehen von den ersten 5 Spalten zum Ausführzeitpunkt) manuell nicht funktioniert, kann crontab auch nicht zaubern.