it-swarm.com.de

Wo kann ich Umgebungsvariablen festlegen, die von crontab verwendet werden?

Ich habe eine Crontab, die jede Stunde läuft. Der Benutzer, der es ausführt, hat Umgebungsvariablen im .bash_profile, die funktionieren, wenn der Benutzer den Job vom Terminal aus ausführt, diese werden jedoch offensichtlich nicht von crontab aufgenommen, wenn sie ausgeführt werden.

Ich habe versucht, sie in .profile und .bashrc aber sie scheinen immer noch nicht abgeholt zu werden. Weiß jemand, wo ich Umgebungsvariablen ablegen kann, die Crontab aufnehmen kann?

243
James

Lassen Sie 'cron' ein Shell-Skript ausführen, mit dem die Umgebung festgelegt wird, bevor Sie den Befehl ausführen.

Immer.

#   @(#)$Id: crontab,v 4.2 2007/09/17 02:41:00 jleffler Exp $
#   Crontab file for Home Directory for Jonathan Leffler (JL)
#-----------------------------------------------------------------------------
#Min     Hour    Day     Month   Weekday Command
#-----------------------------------------------------------------------------
0        *       *       *       *       /usr/bin/ksh /work1/jleffler/bin/Cron/hourly
1        1       *       *       *       /usr/bin/ksh /work1/jleffler/bin/Cron/daily
23       1       *       *       1-5     /usr/bin/ksh /work1/jleffler/bin/Cron/weekday
2        3       *       *       0       /usr/bin/ksh /work1/jleffler/bin/Cron/weekly
21       3       1       *       *       /usr/bin/ksh /work1/jleffler/bin/Cron/monthly

Die Skripte in ~/bin/Cron sind alle Links zu einem einzelnen Skript, 'runcron', das wie folgt aussieht:

:       "$Id: runcron.sh,v 2.1 2001/02/27 00:53:22 jleffler Exp $"
#
#       Commands to be performed by Cron (no debugging options)

#       Set environment -- not done by cron (usually switches HOME)
. $HOME/.cronfile

base=`basename $0`
cmd=${REAL_HOME:-/real/home}/bin/$base

if [ ! -x $cmd ]
then cmd=${HOME}/bin/$base
fi

exec $cmd ${@:+"[email protected]"}

(Geschrieben mit einem älteren Codierungsstandard - heutzutage würde ich am Anfang ein Shebang '#!' Verwenden.)

Die '~/.cronfile' ist eine Variation meines Profils zur Verwendung durch cron - streng nicht interaktiv und kein Echo, um laut zu werden. Sie können stattdessen das .profile usw. ausführen. (Das REAL_HOME-Zeug ist ein Artefakt meiner Umgebung - Sie können so tun, als wäre es dasselbe wie $ HOME.)

Dieser Code liest also die entsprechende Umgebung und führt dann die Nicht-Cron-Version des Befehls in meinem Ausgangsverzeichnis aus. So sieht beispielsweise mein "Wochentag" -Befehl wie folgt aus:

:       "@(#)$Id: weekday.sh,v 1.10 2007/09/17 02:42:03 jleffler Exp $"
#
#       Commands to be done each weekday

# Update ICSCOPE
n.updics

Der Befehl 'daily' ist einfacher:

:       "@(#)$Id: daily.sh,v 1.5 1997/06/02 22:04:21 johnl Exp $"
#
#       Commands to be done daily

# Nothing -- most things are done on weekdays only

exit 0
81

Sie können Umgebungsvariablen in der crontab selbst definieren, wenn Sie crontab -e Über die Befehlszeile ausführen.

LANG=nb_NO.UTF-8
LC_ALL=nb_NO.UTF-8
# m h  dom mon dow   command

* * * * * sleep 5s && echo "yo"

Diese Funktion steht nur bestimmten cron-Implementierungen zur Verfügung. Ubuntu und Debian verwenden derzeit vixie-cron , wodurch diese in der crontab-Datei deklariert werden können (auch GNU mcron ).

Archlinux und RedHat verwenden cronie , wobei keine Umgebungsvariablen zulässt deklariert werden und Syntaxfehler im cron.log auslösen. Problemumgehung kann pro Eintrag erfolgen:

# m h  dom mon dow   command
* * * * * export LC_ALL=nb_NO.UTF-8; sleep 5s && echo "yo"
226
carestad

Ich habe noch eine Lösung für dieses Problem:

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

In diesem Fall werden alle Umgebungsvariablen ausgewählt, die in Ihrer $HOME/.profile - Datei definiert sind.

Natürlich ist $HOME Auch nicht gesetzt, Sie müssen es durch den vollständigen Pfad Ihres $HOME Ersetzen.

134
Vishal

Setzen von Variablen in /etc/environment hat auch für mich in Ubuntu gearbeitet. Ab 12.04 sind Variablen in /etc/environment sind für cron geladen.

48
baxeico

Ein Beispiel für das Erweitern von @carestad, das 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 cron_job.sh Datei:

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

Bei jedem Befehl nach der Quelle von .bash_profile ist Ihre Umgebung so, als ob Sie angemeldet wären.

22
Robert Brisita

Wenn Sie die Skripte starten, die Sie über cron ausführen, verwenden Sie:

#!/bin/bash -l

Sie sollten Ihre ~/.bash_profile - Umgebungsvariablen abholen

22
breizhmg

Für mich musste ich die Umgebungsvariable für eine PHP-Anwendung setzen. Ich habe es durch Hinzufügen des folgenden Codes zu meiner Crontab behoben.

$ Sudo  crontab -e

crontab:

ENVIRONMENT_VAR=production

* * * * * /home/deploy/my_app/cron/cron.doSomethingWonderful.php

und in doSomethingWonderful.php konnte ich den Umgebungswert erhalten mit:

<?php     
echo $_SERVER['ENVIRONMENT_VAR']; # => "production"

Ich hoffe das hilft!

14
karlingen

Was auch immer Sie in crontab einstellen, wird in den Cronjobs sowohl direkt als auch unter Verwendung der Variablen in den Skripten verfügbar sein.

Verwenden Sie sie bei der Definition des Cronjobs

Sie können crontab so konfigurieren, dass Variablen festgelegt werden, die dann vom Cronjob verwendet werden:

$ crontab -l
myvar="hi man"
* * * * * echo "$myvar. date is $(date)" >> /tmp/hello

Nun ist die Datei /tmp/hello zeigt Dinge wie:

$ cat /tmp/hello 
hi man. date is Thu May 12 12:10:01 CEST 2016
hi man. date is Thu May 12 12:11:01 CEST 2016

Verwenden Sie sie in dem von cronjob ausgeführten Skript

Sie können crontab so konfigurieren, dass Variablen festgelegt werden, die dann von den Skripten verwendet werden können:

$ crontab -l
myvar="hi man"
* * * * * /bin/bash /tmp/myscript.sh

Und sag script /tmp/myscript.sh ich mag das:

echo "Now is $(date). myvar=$myvar" >> /tmp/myoutput.res

Es erzeugt eine Datei /tmp/myoutput.res zeigt:

$ cat /tmp/myoutput.res
Now is Thu May 12 12:07:01 CEST 2016. myvar=hi man
Now is Thu May 12 12:08:01 CEST 2016. myvar=hi man
...
10
fedorqui

Anstatt von

0  *  *  *  *  sh /my/script.sh

Benutze bash -l -c

0  *  *  *  *  bash -l -c 'sh /my/script.sh'
6
Ilya Kharlamov

Erweitern von @Robert Brisita wurde gerade erweitert. Wenn Sie nicht alle Variablen des Profils im Skript einrichten möchten, können Sie die zu exportierenden Variablen oben im Skript auswählen

In der crontab -e Datei:

Shell=/bin/bash

*/1 * * * * /Path/to/script/script.sh

In script.sh

#!/bin/bash
export Java_HOME=/path/to/jdk

some-other-command
4
Marcos Pousada

Ein anderer Weg - inspiriert durch diese Antwort - Variablen zu "injizieren" ist der folgende (Beispiel fcron):

%daily 00 12 \
    set -a; \
    . /path/to/file/containing/vars; \
    set +a; \
    /path/to/script/using/vars

Von help set:

-a Markiert Variablen, die für den Export geändert oder erstellt wurden.

Wenn Sie + anstelle von - verwenden, werden diese Flags deaktiviert.

Also alles dazwischen set - und set + wird nach env exportiert und steht dann für andere Skripte usw. zur Verfügung. Ohne die Verwendung von set werden die Variablen zwar bezogen, leben aber nur in set.

Abgesehen davon ist es auch nützlich, Variablen zu übergeben, wenn ein Programm ein Nicht-Root-Konto benötigt, Sie jedoch einige Variablen in der Umgebung des anderen Benutzers benötigen. Im Folgenden finden Sie ein Beispiel für die Übergabe von Nullmailer-Variablen zum Formatieren des E-Mail-Headers:

su -s /bin/bash -c "set -a; \
                    . /path/to/nullmailer-vars; \
                    set +a; \
                    /usr/sbin/logcheck" logcheck
2
Saucier

Ich habe die meisten der angebotenen Lösungen ausprobiert, aber zunächst funktionierte nichts. Es stellte sich jedoch heraus, dass es nicht die Lösungen waren, die nicht funktionierten. Anscheinend beginnt meine ~/.bashrc - Datei mit dem folgenden Codeblock:

case $- in
    *i*) ;;
    *) return;;
esac

Dies ist im Grunde genommen ein case statement, Der die aktuellen Optionen in der aktuellen Shell überprüft, um festzustellen, ob die Shell interaktiv ausgeführt wird. Wenn die Shell zufällig interaktiv ausgeführt wird, fährt sie mit der Suche nach der Datei ~/.bashrc Fort. In einer Shell, die von cron aufgerufen wird, enthält die Variable $- Jedoch nicht den Wert i, der die Interaktivität angibt. Daher wird die Datei ~/.bashrc Niemals vollständig beschafft. Infolgedessen wurden die Umgebungsvariablen nie festgelegt. Wenn dies Ihr Problem ist, können Sie den Codeblock wie folgt auskommentieren und es erneut versuchen:

# case $- in
#     *i*) ;;
#     *) return;;
# esac

Ich hoffe, dass sich dies als nützlich herausstellt

2
Abdou

Ich verwende Oh-my-zsh In meinem MacBook, also habe ich viele Dinge versucht, um die Ausführung der crontab-Aufgabe zu erreichen, aber schließlich stellte meine Lösung den .zshrc Vor dem auszuführenden Befehl.

*/30 * * * * . $HOME/.zshrc; node /path/for/my_script.js

Diese Task wird alle 30 Minuten ausgeführt und verwendet das Profil .zshrc, Um meinen Knotenbefehl auszuführen.

Vergessen Sie nicht, den Punkt vor der Variable $HOME Zu verwenden.

1
Alekosdat