Crontab-Umgebung

7

Ich habe verschiedene Skripte geschrieben, um Java-Serveranwendungen zu starten, die normalerweise 24 Stunden lang ausgeführt werden, bevor sie heruntergefahren werden (indem dasselbe Skript mit einem anderen Parameter aufgerufen wird).

Das Skript basiert auf Umgebungsvariablen, die in einer Datei definiert sind ~/<user>.env:, aus der ich eine Quelle habe .bashrc.

Dies funktioniert einwandfrei, wenn das Skript über die Befehlszeile aufgerufen wird. Wenn ich das Skript jedoch als Crontab-Eintrag hinzufügen möchte, tritt das Problem auf, bei dem .bashrces nicht gelesen wird.

Meine Frage: Was ist der Best-Practice-Ansatz zur Lösung dieses Problems? Mir ist klar, dass ich einen Crontab-Eintrag definieren könnte, wie zum Beispiel:

* * * * 1-5 /usr/bin/bash -c '. /home/myuser/myuser.env && /home/myuser/scripts/myscript.sh'

... aber das scheint einfach hässlich. Alternativ könnte ich myuser.envam Anfang jedes Skripts eine Quelle finden , aber dies wäre ein Albtraum, den man aufrechterhalten muss.

Jede Hilfe geschätzt.

Adamski
quelle
Das sind die beiden Optionen, die ich vorschlagen würde.
einstiien

Antworten:

11

Normalerweise adressiere ich dies mit einem kurzen Cron-Wrapper-Skript:

#!/bin/bash
[ -r $HOME/.bashrc ] && . $HOME/.bashrc
[ -r $HOME/.profile ] && . $HOME/.profile
exec "$@"

Stellen Sie dann dem Befehl in crontab einfach Ihren Wrapper voran:

* * * * 1-5 ~/scripts/cron-wrapper ~/scripts/myscript.sh
* * * * 1-5 ~/scripts/cron-wrapper ~/scripts/myotherscript.sh

In einigen Versionen von cron können Sie Variablen direkt in crontab festlegen. Leider kann ich diese bei der Arbeit nicht verwenden.

pra
quelle
10

Ich habe tatsächlich eine ziemlich elegante Lösung gefunden, indem ich meinem bash-Befehl das Flag '-l' (--login) hinzugefügt habe, wodurch alle Anmeldedateien, einschließlich .bashrc, als Quelle verwendet werden. Daher lautet mein Crontab-Befehl einfach:

* * * * 1-5 /usr/bin/bash -lc '/mnt/group/core/deploy/scripts/test.sh' > /dev/null 2>&1
Adamski
quelle
3

Eine alternative (wenn auch nicht unbedingt bessere) Option wäre, diese in die crontab von root einzufügen und den Eintrag su mit einem Bindestrich verwenden zu lassen, um der betreffende Benutzer zu werden. Die Umgebungsvariablen würden dann automatisch über die Standard-Shell-Umgebung des Benutzers in ~ / .bashrc oder dergleichen abgerufen. z.B:

* * * * 1-5 su - scriptuser '/home/myuser/scripts/myscript.sh' Dies würde den Job als Skriptbenutzer mit allen Umgebungsvariablen einer ordnungsgemäßen Anmeldung ausführen. Der Nachteil ist, dass der Skriptbenutzer diesen Job selbst nicht einrichten konnte - dafür wären Root-Berechtigungen erforderlich.

Christopher Karel
quelle
1

Die Cron-Wrapper-Lösung funktionierte für mich mit einer Änderung. Ich musste das $ HOME durch den absoluten Pfad zum Benutzer-Home-Ordner ersetzen. In diesem Fall war es:

#!/bin/bash
[ -r /root/.bashrc ] && . /root/.bashrc
[ -r /root/.profile ] && . /root/.profile
exec "$@"
Datageek
quelle
0

Das einzige andere, woran ich denken kann, wäre:

bash -i --rcfile 'init' -c 'script'

das ist wahrscheinlich weniger attraktiv.

Bis auf weiteres angehalten.
quelle
Ich habe es tatsächlich versucht und es funktioniert nicht. Laut dem GNU-Bash-Handbuch ist --rcfile "Befehle aus dem Dateinamen (anstelle von ~ / .bashrc) in einer interaktiven Shell ausführen", und da ich keine interaktive Shell ausführe, gehe ich davon aus, dass dies der Grund ist, warum dies fehlschlägt.
Adamski
@Adamski: Das -ilässt die Shell denken, dass sie interaktiv ist.
Bis auf weiteres angehalten.
0

In neueren Versionen von cron können Sie beliebige Umgebungsvariablen festlegen, bevor Sie Jobs ausführen. Sie können dies also zu Ihrer Crontab hinzufügen:

CRON = 1

Dann machen Sie in Ihrem .bash_login so etwas:

[-n "$ CRON"] &&. .bashrc

digdug
quelle