it-swarm.com.de

Wie kann ich einen Cron-Befehl mit vorhandenen Umgebungsvariablen ausführen?

Wie kann ich einen Cron-Befehl mit vorhandenen Umgebungsvariablen ausführen?

Wenn ich an einer Shell-Eingabeaufforderung bin, kann ich echo $Oracle_HOME Eingeben und einen Pfad abrufen. Dies ist eine meiner Umgebungsvariablen, die in meinem ~/.profile Festgelegt wird. Es scheint jedoch, dass ~/.profile Nicht aus Cron-Skripten geladen wird und meine Skripte daher fehlschlagen, weil die Variable $Oracle_HOME Nicht gesetzt ist.

In diese Frage erwähnt der Autor das Erstellen eines ~/.cronfile - Profils, das Variablen für cron einrichtet, und führt dann eine Problemumgehung durch, um alle seine cron-Befehle in Skripte zu laden, die er in seinem ~/Cron Verzeichnis. Eine Datei wie ~/.cronfile Klingt nach einer guten Idee, aber der Rest der Antwort scheint etwas umständlich zu sein, und ich hatte gehofft, jemand könnte mir einen einfacheren Weg nennen, um das gleiche Ergebnis zu erzielen.

Ich nehme an, ich könnte zu Beginn meiner Skripte so etwas wie source ~/.profile Hinzufügen, aber das scheint überflüssig zu sein.

Wie kann ich meine Cron-Skripte dazu bringen, die Variablen aus meinem Interactive-Shell-Profil zu laden?

126
cwd

Fügen Sie in der Crontab vor dem Befehl . $HOME/.profile. Zum Beispiel:

0 5 * * * . $HOME/.profile; /path/to/command/to/run

Cron weiß nichts über Ihre Shell; Es wird vom System gestartet, hat also eine minimale Umgebung. Wenn Sie etwas wollen, müssen Sie das selbst mitbringen lassen.

154
Arcege

Eine andere Option, die ich einfacher finde, besteht darin, das Skript mit cron auszuführen und die Umgebung im Skript zu haben.

In der crontab -e Datei:

Shell=/bin/bash

*/1 * * * * $HOME/cron_job.sh

In der Datei cron_job.sh:

#!/bin/bash
source $HOME/.bash_profile
some_other_cmd

Jeder Befehl nach der Quelle von .bash_profile hat Ihre Umgebung so, als ob Sie angemeldet wären.

45
Robert Brisita

Eine andere Option, die ich einfacher finde, besteht darin, das Skript mit cron auszuführen und bash anzuweisen, sich anzumelden (daher /etc/profile.d/... Umgebungsdefinitionen)

Im crontab -e Datei:

*/1 * * * * bash -l -c './cron_job.sh'
*/1 * * * * bash -l -c 'php -f ./cron_job.php'

Jeder Befehl nach der Quelle von .bash_profile hat Ihre Umgebung so, als ob Sie angemeldet wären.

24
Artistan

Schlechte Idee. In der Regel werden alle erforderlichen Umgebungsvariablen in einem Skript festgelegt, das von einem Cron-Job ausgeführt werden soll.

10
fpmurphy

Diese Syntax hilft Ihnen definitiv. Ich verstehe die Syntax nicht, aber es funktioniert. Oracle verwendet diese Syntax, wenn Oracle Configuration Manager für crontab bereitgestellt wird. Daher halte ich dies für die richtige Lösung.

0 5 * * * SOME_ENV_VAR=some_value some_command some_parameters
6
meir

Sie können globale Umgebungsvariablen in /etc/environment. Sie werden geladen, wenn ein Programm von der Crontab ausgeführt wird. Ex :

env | grep Oracle_HOME >> /etc/environment
service crontab restart

Der Nachteil ist, dass es nicht auf einen einzelnen Benutzer beschränkt ist. Getestet unter CentOS7

3
Kiruahxh

Ich bin kürzlich auf einen Fall gestoßen, in dem ich den gesamten Cronjob als root ausführen musste, aber gleichzeitig einen Unterbefehl als einen anderen Benutzer ausführen musste (was die Beschaffung der Umgebung dieses Benutzers erforderte). Ich ging mit folgendem Ansatz vor:

# m  h  dom  mon  dow  user  command
*/5  *   *    *    *   root  (Sudo -i -u <the user> command-to-be-run-as-user) && command-to-be-run-as-root

Der entscheidende Teil ist das Argument -i, Das an Sudo übergeben wird, das den angegebenen Befehl in einer separaten Anmeldeshell ausführt (was wiederum bedeutet, dass die Punktedateien des Benutzers bezogen werden).

PS: Beachten Sie, dass die Spalte user nur in den Dateien /etc/crontab Und /etc/cron.d/* Verfügbar ist.

2
balu

Ja, Sie können "bekannte Problemumgehungen" verwenden (von denen einige aufgelistet wurden). Dies ist eine andere Art zu sagen, dass jeder weiß, dass es beschissen ist, obwohl einige Leute dies als "Sicherheitsmerkmal" bezeichnen, weil sie mindestens so viel Zeit damit verbracht haben, über diesen Fehler zu stolpern (ure) wie Sie und dies gerne glauben würden Zeitverschwendung war nicht umsonst. Es ist das Cron-Äquivalent der Tastatur QWERTY).

Ich vermute, der ursprüngliche Grund war möglicherweise die Leistung, sodass Skripte, die einmal pro Minute ausgeführt werden, nicht die Zeit zum Lesen von RC-Skripten aufwenden würden. Auch ursprünglich war cron überhaupt nicht wirklich konfigurierbar, so dass ein Standard wirklich die einzige Option war.

Es gibt keine zusätzliche Sicherheit, da keine einfache Konfiguration oder Methode vorhanden ist, mit der cron nur die Umgebung Ihrer interaktiven Shell übernimmt, anstatt dass Benutzer dumme Shell-Gymnastik ausführen müssen. Auf einer modernen Maschine ist im Allgemeinen kein Leistungsgewinn erkennbar, es sei denn, Sie führen jede Minute eine große Anzahl von Jobs aus.

Unix-Kultur scheitert. Meiner bescheidenen Meinung nach. :-)

1
Austin S.

Anstatt ein Profil festzulegen, half mir das Festlegen von PATH. Einige der Befehle waren in meinen Cron-Skripten nicht verfügbar, da PATH anders ist.

ENVIRONMENT=prod
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
*/30 * * * * /opt/myscript1.sh
*/30 * * * * /opt/myscript2.sh
*/30 * * * * /opt/myscript3.sh

Das Setzen von PATH mit dem Befehlspfad hat mir geholfen. Noch besser, wenn Sie eine Vorlage verwenden und später detemplatisieren können.

ENVIRONMENT={{ENVIRONMENT}}
PATH={{PATH}}
*/30 * * * * /opt/myscript1.sh
*/30 * * * * /opt/myscript2.sh
*/30 * * * * /opt/myscript3.sh

Das Übergeben von Variablen an jedes Element sieht unübersichtlich aus.

1
Optimus Prime

Die Lösung, die für mich funktioniert hat, wird beschrieben hier .

Sie erstellen ein Wrapper-Skript, das . ~/.cronfile und macht dann die Dinge, die Sie wollen. Dieses Skript wird von cron gestartet.

Im ~/.cronfile Sie geben die Umgebung für Ihre Cron-Jobs an.

1
weekens

Hinzufügen

BASH_ENV=/home/user/.profile

zum crontab. Siehe So garantieren Sie die Verfügbarkeit von $ BASH_ENV

1
Enno