Ich möchte in der Lage sein, programmgesteuert einen neuen Cron-Job hinzuzufügen. Wie kann ich das am besten tun?
Aus meiner Recherche scheint es, als könnte ich die aktuelle Crontab ausgeben und dann eine neue anhängen, die dann zurück in die Crontab geht:
(crontab -l ; echo "0 * * * * wget -O - -q http://www.example.com/cron.php") | crontab -
Gibt es einen besseren Weg?
Wenn Sie als root arbeiten, legen Sie am besten eine Datei in /etc/cron.d ab
wenn Sie zum Packen Ihrer Software einen Paket-Manager verwenden, können Sie einfach Dateien in diesem Verzeichnis ablegen und sie werden so interpretiert, als wären sie Crontabs, aber mit einem zusätzlichen Feld für den Benutzernamen, z.
Dateiname: /etc/cron.d/per_minute
Inhalt: * * * * * root /bin/sh /home/root/script.sh
Die Lösung von OP weist einen Fehler auf. Möglicherweise können Einträge zweimal hinzugefügt werden.
(crontab -l ; echo "0 * * * * your_command") | sort - | uniq - | crontab -
Etwas zu cron hinzufügen
(crontab -l ; echo "0 * * * * hupChannel.sh") 2>&1 | grep -v "no crontab" | sort | uniq | crontab -
Um dies von cron zu entfernen
(crontab -l ; echo "0 * * * * hupChannel.sh") 2>&1 | grep -v "no crontab" | grep -v hupChannel.sh | sort | uniq | crontab -
hoffe würde jemandem helfen
Wenn Sie vorhaben, ein Run-Once-Szenario auszuführen, um nur etwas zu tun, schauen Sie sich bitte 'at' an.
Ändern Sie einfach den Editor zum Abschlagbefehl:
export EDITOR="tee"
echo "0 * * * * /bin/echo 'Hello World'" | crontab -e
Vorausgesetzt, es gibt bereits einen Eintrag in Ihrer Crontab, sollte der folgende Befehl relativ gut funktionieren. Beachten Sie, dass die Variable $CMD
nur zur besseren Lesbarkeit vorhanden ist. Das Sortieren vor dem Filtern von Duplikaten ist wichtig, da uniq
nur für benachbarte Zeilen funktioniert.
CMD='wget -O - -q http://www.example.com/cron.php"'
(crontab -l ; echo "0 * * * * $CMD") | sort | uniq | crontab -
Wenn Sie derzeit eine leere Crontab haben, erhalten Sie folgende Fehlermeldung an stderr:
no crontab for user
Wenn Sie dies vermeiden möchten, können Sie ein wenig Komplexität hinzufügen und etwas wie folgt hinzufügen:
(crontab -l ; echo "0 * * * * $CMD") 2>&1 | sed "s/no crontab for $(whoami)//" | sort | uniq | crontab -
Zu JohnZs Antwort kommt noch folgende Syntax, die Sie als root einplanen sollten, wenn Sie ein Sudoer sind:
(Sudo crontab -l ; echo "0 * * * * your_command") | sort - | uniq - | Sudo crontab -
function cronjob_exists($command){
$cronjob_exists=false;
exec('crontab -l', $crontab);
if(isset($crontab)&&is_array($crontab)){
$crontab = array_flip($crontab);
if(isset($crontab[$command])){
$cronjob_exists=true;
}
}
return $cronjob_exists;
}
function append_cronjob($command){
if(is_string($command)&&!empty($command)&&cronjob_exists($command)===FALSE){
//add job to crontab
exec('echo -e "`crontab -l`\n'.$command.'" | crontab -', $output);
}
return $output;
}
append_cronjob('* * * * * curl -s http://localhost/cron/test.php');
Die meisten Lösungen hier sind für das Hinzufügen von Zeilen zur Crontab. Wenn Sie mehr Kontrolle benötigen, sollten Sie den gesamten Inhalt der Crontab steuern können.
Sie können Paspeln verwenden, um dies ziemlich elegant zu tun.
Um das Crontab vollständig neu zu schreiben, tun Sie
echo "2 2 2 2 2 /bin/echo foobar" |crontab -
Dies sollte leicht mit anderen hier beschriebenen Antworten kombiniert werden können
crontab -l | <something> | tee |crontab -
Wenn Sie den Inhalt in einer Datei haben, ist dies noch einfacher
cat <file> |crontab -
man crontab ist auch nützlich:
CRONTAB (1)
NAME
crontab - manipulate per-user crontabs (Dillon's Cron)
ZUSAMMENFASSUNG
crontab file [-u user] - replace crontab from file
crontab - [-u user] - replace crontab from stdin
crontab -l [user] - list crontab for user
Damit prüfen Sie, ob Ihr Befehl noch nicht vorhanden ist, bevor Sie ihn hinzufügen.
crontab -l 2>/dev/null | grep -q '/path/to/script' || echo "5 * * * * /path/to/script" | crontab -
Prost.
Hier ist ein weiterer Einzeilerweg, der Duplikate vermeidet
(crontab -l 2>/dev/null | fgrep -v "*/1 * * * * your_command"; echo "*/1 * * * * your_command") | crontab -
Hier ist eine Möglichkeit, die Antwort von JohnZ auszuführen und die no crontab for user
-Nachricht zu vermeiden, oder wenn Sie in einer set -eu
-Umgebung arbeiten müssen und keinen Fehler zurückgeben können (in diesem Fall ist der 2>/dev/null
-Teil optional):
( (crontab -l 2>/dev/null || echo "") ; echo "0 * * * * your_command") | sort -u - | crontab -
Oder wenn Sie die Dinge so aufteilen möchten, dass sie lesbarer sind:
new_job="0 * * * * your_command"
preceding_cron_jobs=$(crontab -l || echo "")
(echo "$preceding_cron_jobs" ; echo "$new_job") | sort - | uniq - | crontab -
Oder entfernen Sie optional alle Verweise auf Ihren_Befehl (Beispiel: Wenn sich der Zeitplan geändert hat, möchten Sie, dass er nur einmal aufgerufen wird). In diesem Fall brauchen wir uniq
nicht mehr (hinzugefügter Bonus, Einfügereihenfolge wird auch beibehalten):
new_job="0 * * * * your_command"
preceding_cron_jobs=$(crontab -l || echo "")
preceding_cron_jobs=$(echo "$preceding_cron_jobs" | grep -v your_command )
(echo "$preceding_cron_jobs" ; echo "$new_job") | crontab -
Das Übertragen von stdout in crontab
hat die neue Crontab auf MacOS nicht für mich installiert. Daher habe ich diese Lösung mit dem tee
-Editor in einer Sub-Shell gefunden:
(EDITOR=tee && (crontab -l ; echo "@daily ~/my-script.sh" ) | uniq - | crontab -e)