staging.inyokaproject.org

Crontab per Script setzen

Status: Gelöst | Ubuntu-Version: Server 20.04 (Focal Fossa)
Antworten |

regenpfeifer

Avatar von regenpfeifer

Anmeldungsdatum:
18. April 2006

Beiträge: 993

Hallo zusammen,

ich suche nach einer Möglichkeit, einen Cronjob per Bash-Script ohne Benutzer-Interaktion zu setzen.

Konkret mache ich das im fraglichen Fall so, dass ich

1
crontab -u www-data -e

aufrufe und dann manuell den Eintrag vornehme.

Gibt es einen Weg, dies direkt in eine Datei einzutragen? Ich habe recherchiert und dabei dies gefunden:

1
(crontab -l 2>/dev/null; echo "*/5 * * * * /path/to/job -with args") | crontab -

Zu einen weiß ich aber leider nicht genau, was dieser Befehl wirklich macht, zum anderen scheint hier der Eintrag nicht für den Crontab eines bestimmten Benutzers zu erfolgen (in meinem Fall www-data). Jedenfalls scheint es mit

1
(crontab -u www-data -l 2>/dev/null; echo "*/5 * * * * /path/to/job -with args") | crontab -

nicht zu funktionieren.

Hat jemand einen Hinweis und / oder Verbesserungsvorschlag? Danke!

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13242

regenpfeifer schrieb:

1
(crontab -l 2>/dev/null; echo "*/5 * * * * /path/to/job -with args") | crontab -

Zu einen weiß ich aber leider nicht genau, was dieser Befehl wirklich macht,

Er liest die aktuelle Crontab aus, gibt eine weitere Zeile aus (den neuen Eintrag) und sendet beides verkettet wieder zu crontab, was letztlich die Crontab aktualisiert.

zum anderen scheint hier der Eintrag nicht für den Crontab eines bestimmten Benutzers zu erfolgen (in meinem Fall www-data). Jedenfalls scheint es mit

1
(crontab -u www-data -l 2>/dev/null; echo "*/5 * * * * /path/to/job -with args") | crontab -

nicht zu funktionieren.

Ja, weil beim letzten crontab in der Zeile die Option "-u" nebst Angabe des Nutzers fehlt. Die runden Klammern sind übrigens überflüssig.

Hat jemand einen Hinweis und / oder Verbesserungsvorschlag? Danke!

Der Ansatz funktioniert, wird aber bei jedem Aufruf einen neuen Eintrag in der Crontab machen. Das will man normalerweise nicht. Am besten fügt man eine Markierung ein, an der man erkennt, dass bereits ein Eintrag da ist. Zur Illustration (ohne crontab):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
$ touch demo
$ wc demo
0 0 0 demo
$ { sed '/^# DEMO/,+1d' demo; echo -e '# DEMO: automatic execution of X\n*/5 * * * * /path/to/job -with args'; } >| demo.tmp
$ mv -f demo.tmp demo
$ cat demo
# DEMO: automatic execution of X
*/5 * * * * /path/to/job -with args
$ { sed '/^# DEMO/,+1d' demo; echo -e '# DEMO: automatic execution of X\n*/5 * * * * /path/to/job -with args new'; } >| demo.tmp
$ mv -f demo.tmp demo
$ cat demo 
# DEMO: automatic execution of X
*/5 * * * * /path/to/job -with args new

Jetzt mal mit einem weiteren Eintrag:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
$ echo '* * * * * /bin/foo' >> demo 
$ cat demo 
# DEMO: automatic execution of X
*/5 * * * * /path/to/job -with args new
* * * * * /bin/foo
$ { sed '/^# DEMO/,+1d' demo; echo -e '# DEMO: automatic execution of X\n*/5 * * * * /path/to/job -with args new'; } >| demo.tmp
$ mv -f demo.tmp demo
$ cat demo 
* * * * * /bin/foo
# DEMO: automatic execution of X
*/5 * * * * /path/to/job -with args new

Man sieht, der Eintrag von /bin/foo bleibt erhalten.

kB Team-Icon

Supporter, Wikiteam
Avatar von kB

Anmeldungsdatum:
4. Oktober 2007

Beiträge: 9837

crontab kann entweder nur mit einer Option -l, -r, -e oder mit dem Namen einer Datei aufgerufen werden. Im letzten Fall wird die Crontab-Datei des Benutzers durch die angegebene Datei ersetzt. Der spezielle Dateiname „-“ bedeutet als Pseudodateiname „nimm stdin“.

In allen Fällen kann mit der Option -u der Name eines Benutzers angegeben werden, dessen Crontab-Datei dann entsprechend modifiziert wird. Zur Bearbeitung der Crontab-Datei eines anderen Benutzers benötigt man natürlich eine passende Berechtigung.

Das Ganze macht natürlich nur dann Sinn, wenn überhaupt ein Cron-Daemon aktiv ist. Da Cron nicht vom systemd-Projekt erfunden wurde, stellen dessen Mitglieder über Timer-Units eine eigene Methode zur Verfügung.

regenpfeifer

(Themenstarter)
Avatar von regenpfeifer

Anmeldungsdatum:
18. April 2006

Beiträge: 993

Danke, kB, für die Erklärung der crontab-Optionen. Und danke an rklm für einen möglichen Lösungsansatz.

Grundlegend funktioniert es nun mit dieser Zeile:

1
crontab l 2>/dev/null; echo "*/5 * * * * /path/to/job -with args" | crontab -u www-data - -

Nachdem das Ganze für ein Installationsscript gedacht ist, wo der Befehl nur einmal aufgerufen wird, wäre dies evtl. ausreichend. Allerdings macht dieses Vorgehen nicht jedes Mal einen neuen Eintrag, sondern ersetzt den Inhalt der crontab durch die neue Zeile.

Daher werde ich mir die Lösung von rklm mit der Markierung noch genauer anschauen und muss dann aber noch sehen, wie ich dies für crontab umsetze (das ist mir noch nicht so ganz klar...)

kB Team-Icon

Supporter, Wikiteam
Avatar von kB

Anmeldungsdatum:
4. Oktober 2007

Beiträge: 9837

regenpfeifer schrieb:

[…]

crontab l 2>/dev/null; echo "*/5 * * * * /path/to/job -with args" | crontab -u www-data - -

[…] Allerdings macht dieses Vorgehen nicht jedes Mal einen neuen Eintrag, sondern ersetzt den Inhalt der crontab durch die neue Zeile.

Wenn Du zur bestehenden Crontab etwas hinzufügen möchtest, benötigst Du Klammern, weil der Operator „|“ stärker bindet als der Operator „;“. Außerdem die Option "-l" richtig schreiben:

{ crontab -l 2>/dev/null; echo "*/5 * * * * /path/to/job -with args" ;} | crontab -u www-data - - 

oder (aber Subshell ist hier Verschwendung):

( crontab -l 2>/dev/null; echo "*/5 * * * * /path/to/job -with args" ) | crontab -u www-data - - 

regenpfeifer

(Themenstarter)
Avatar von regenpfeifer

Anmeldungsdatum:
18. April 2006

Beiträge: 993

Besten Dank, kB, jetzt funktioniert es!

Antworten |