Wie kann ich einen Cron-Befehl mit vorhandenen Umgebungsvariablen ausführen?
Wenn ich an einer Shell-Eingabeaufforderung bin, kann echo $ORACLE_HOME
ich einen Pfad eingeben und abrufen. Dies ist eine meiner Umgebungsvariablen, die in my gesetzt wird ~/.profile
. Es scheint jedoch, dass von ~/.profile
Cron-Skripten keine geladen werden und meine Skripten fehlschlagen, weil die $ORACLE_HOME
Variable nicht gesetzt ist.
In dieser 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 Skripten zu laden, die er in seinem ~/Cron
Verzeichnis aufbewahrt. Eine Datei ~/.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, zu Beginn meiner Skripte könnte ich so etwas hinzufügen, source ~/.profile
aber das scheint so, als könnte es überflüssig sein.
Wie kann ich meine Cron-Skripte dazu bringen, die Variablen aus meinem Interactive-Shell-Profil zu laden?
source ~/.profile
zu einem Programm überflüssig? Programme erben ihre Umgebung vom aufrufenden Programm. Wenn dieses aufrufende Programm nicht Ihre Shell ist, wie erhält dann das untergeordnete Programm die gewünschte Umgebung?su -l
um eine normale Anmeldeumgebung einzurichten, die den $ PATH für den Root-Benutzer oder einen anderen bestimmten Benutzer enthält.Antworten:
Fügen Sie in der Crontab, bevor Sie befehlen, hinzu
. $HOME/.profile
. Zum Beispiel:Cron
weiß nichts über deine Muschel; Es wird vom System gestartet, daher ist die Umgebung minimal. Wenn Sie etwas wollen, müssen Sie das selbst mitbringen.quelle
.
vor dem Drehbuch? (nicht sicher, wie ich das machen würdeman
). Warum ist das anders alssource
?.
Befehl ist der ursprüngliche Befehl fürsource
. Sie sind innerhalb der Shell gleichwertig und etwas einfacher zu tippen, insbesondere innerhalb einer Crontab. Für weitere Informationen, geben Sie erhaltenhelp .
oder für die Suche^SHELL BUILTIN COMMANDS
nach in der Manpagebash
oder an der Spitze desman
zshbuiltins. Running
Typs .` werden Ihnen sagen , dass der Befehl ein builtin ist..profile
durch.bash_profile
. Überprüfen Sie, welche.profile
Datei im Ausgangsverzeichnis des Benutzers vorhanden ist.Eine andere Möglichkeit, die ich einfacher finde, besteht darin, das Skript mit cron auszuführen und die Umgebung im Skript zu haben.
In der crontab -e Datei:
In der cron_job.sh Datei:
Bei jedem Befehl nach der Quelle von .bash_profile ist Ihre Umgebung so, als ob Sie angemeldet wären.
quelle
/bin/bash
als Shell verwendet wird. Ich habe mich immer wieder gefragt, warum Dinge wiecd /path/to/project; source .vars
funktionieren, wenn ich sie manuell eingetippt habe, aberFile not found
wenn sie in einem Cronjob enthalten sind, versagen sie ( ). Die Schlüsselzeile für mich war die EinstellungSHELL=/bin/bash
, dass ich in jedem Cronjob vertraute Bash-Befehle verwenden konnte./bin/sh/
(die Standard-Cron-Shell anscheinend) ist sehr einschränkend.EnvironmentFile
Serviceeinheit. Schade, dass cron so etwas nicht hat.$SHELL
ja/bin/sh
, ist dersource
Befehl nicht vorhanden. Verwenden Sie.
stattdessen.Eine andere Möglichkeit, die ich einfacher finde, ist, das Skript mit cron auszuführen und bash anzuweisen, sich anzumelden (daher
/etc/profile.d/...
Umgebungsdefinitionen zu verwenden).In der
crontab -e
Datei:Jeder Befehl nach der Quelle von
.bash_profile
hat Ihre Umgebung so, als ob Sie angemeldet wären.quelle
Schlechte Idee. In der Regel werden alle erforderlichen Umgebungsvariablen in einem Skript festgelegt, das von einem Cron-Job ausgeführt werden soll.
quelle
/usr/bin/env
die Variablen mit dem Befehl set- zen und dann als Umgebungsprozess für den cronjob fungieren.envdir
kommt auch in den Sinn.~/.cronvars
und diese in das Profil und auch in meine Cron-Skripte aufnehmen. Ich möchte Umgebungsvariablen in den Skripten, die ich ausführe, nicht hart codieren, da es nicht einfach ist, fest codierte Pfade in jeder Datei zu verwalten, wenn Pfade geändert werden. Anscheinend würde dies einen zentralen Ort für die benötigten Variablen ermöglichen und verhindern, dass andere Variablen geladen werden.Diese Syntax hilft Ihnen auf jeden Fall. 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 eine richtige Lösung.
quelle
Ich bin kürzlich auf einen Fall gestoßen, in dem ich den gesamten Cronjob als root ausführen musste, gleichzeitig aber einen Unterbefehl als anderer Benutzer ausführen musste (was die Beschaffung der Umgebung dieses Benutzers erforderte). Ich bin mit folgendem Ansatz vorgegangen:
Der entscheidende Teil ist das Argument
-i
, ansudo
das übergeben wird, um den angegebenen Befehl in einer separaten Anmeldeshell auszuführen (was wiederum bedeutet, dass die Punktedateien des Benutzers bezogen werden).PS: Beachten Sie, dass die
user
Spalte nur in/etc/crontab
und den/etc/cron.d/*
Dateien verfügbar ist .quelle
Die Lösung, die bei mir funktioniert hat, ist hier beschrieben .
Sie erstellen ein Wrapper-Skript, das aufruft
. ~/.cronfile
und dann die gewünschten Aktionen ausführt. Dieses Skript wird von cron gestartet.In
~/.cronfile
legen Sie die Umgebung für Ihre Cronjobs fest.quelle
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 werden, weil sie mindestens so viel über dieses Versagen (ure) gestolpert haben, wie Sie es getan haben, und gerne an ihr denken würden Zeitverschwendung war nicht umsonst. Es ist das Cron-Äquivalent der QWERTZ-Tastatur.
Ich vermute, dass der ursprüngliche Grund für die Leistung war, so dass Skripte, die einmal pro Minute ausgeführt werden, nicht die Zeit zum Lesen von RC-Skripten verschwenden würden. Auch ursprünglich war cron überhaupt nicht konfigurierbar, so dass ein Standard die einzige Option war.
Es gibt keine zusätzliche Sicherheit, da cron keine einfache Konfiguration oder Methode hat, um nur die Umgebung Ihrer interaktiven Shell zu übernehmen, anstatt dass Benutzer dumme Shell-Gymnastik machen müssen. Auf einer modernen Maschine ist in der Regel kein Leistungszuwachs erkennbar, es sei denn, Sie haben jede Minute eine große Menge von Aufträgen ausgeführt.
Unix-Kultur scheitert. Meiner bescheidenen Meinung nach. :-)
quelle
Hinzufügen
zur Crontab. Siehe So stellen Sie die Verfügbarkeit von $ BASH_ENV sicher
quelle
Anstatt ein Profil festzulegen, half mir das Festlegen des
PATH
. Einige der Befehle waren in meinen Cron-Skripten nicht verfügbar, da diesPATH
anders ist.Das Setzen
PATH
mit dem Befehlspfad hat mir geholfen. Noch besser, wenn Sie eine Vorlage verwenden und später wieder nachdenken können,Das Übergeben von Variablen an jedes Element sieht unordentlich aus.
quelle
Ich legte .
~/.dbus/session-bus/*
ganz oben auf meinem Wunschskript :)quelle