Où puis-je définir des variables d'environnement que crontab utilisera?
-
19-09-2019 - |
Question
J'ai un crontab en cours d'exécution toutes les heures. L'utilisateur exécutant a environnement variabless dans le .bash_profile
qui fonctionne lorsque l'utilisateur exécute le travail à partir du terminal, mais, évidemment ceux-ci ne sont pas repris par crontab quand il fonctionne.
Je l'ai essayé de les mettre en .profile
et .bashrc
mais ils ne semblent pas encore obtenir ramassé. Est-ce que quelqu'un sait où je peux mettre l'environnement vars que crontab peut ramasser?
La solution
'Cron' Have exécuter un script shell qui définit l'environnement avant d'exécuter la commande.
Toujours.
# @(#)$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
Les scripts dans ~ / bin / Cron sont tous les liens vers un seul script, 'runcron', qui ressemble à:
: "$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 ${@:+"$@"}
(écrit en utilisant une norme de codage plus -. De nos jours, j'utiliser un tralala « ! # » Au début)
Le « ~ / .cronfile » est une variation sur mon profil pour une utilisation par Cron - rigoureusement non interactif et sans écho pour le plaisir d'être bruyant. Vous pouvez prendre des dispositions pour exécuter le .profile et ainsi de suite à la place. (Les trucs de REAL_HOME est un artefact de mon environnement -. Vous pouvez faire semblant est le même que $ HOME)
Alors, ce code lit l'environnement approprié et exécute ensuite la version non-Cron de la commande de mon répertoire personnel. Ainsi, par exemple, ma commande « semaine » ressemble à:
: "@(#)$Id: weekday.sh,v 1.10 2007/09/17 02:42:03 jleffler Exp $"
#
# Commands to be done each weekday
# Update ICSCOPE
n.updics
La commande 'quotidienne' est plus simple:
: "@(#)$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
Autres conseils
Vous pouvez définir des variables d'environnement dans le crontab lui-même lors de l'exécution crontab -e
de la ligne de commande.
LANG=nb_NO.UTF-8
LC_ALL=nb_NO.UTF-8
# m h dom mon dow command
* * * * * sleep 5s && echo "yo"
Cette fonctionnalité est uniquement disponible pour certaines implémentations de Cron. Ubuntu et Debian utilisent actuellement Vixie-cron qui permet de les déclarer dans le fichier crontab (également GNU mcron ).
Archlinux et RedHat utiliser qui cronie ne pas permettent des variables d'environnement à déclarer et jetteront les erreurs de syntaxe dans la cron.log. Solution peut être fait par entrée:
# m h dom mon dow command
* * * * * export LC_ALL=nb_NO.UTF-8; sleep 5s && echo "yo"
Je suis une solution plus pour ce problème:
0 5 * * * . $HOME/.profile; /path/to/command/to/run
Dans ce cas, il choisira toute la variable d'environnement définie dans votre fichier $HOME/.profile
.
Bien sûr $HOME
est pas non plus défini, vous devez le remplacer par le chemin complet de votre $HOME
.
Réglage vars dans /etc/environment
a également travaillé pour moi dans Ubuntu. A partir de 12.04, variables /etc/environment
sont chargées Cron.
Développant exemple @carestad, que je trouve plus facile, est d'exécuter le script avec Cron et ont l'environnement dans le script.
Dans crontab -e fichier:
SHELL=/bin/bash
*/1 * * * * $HOME/cron_job.sh
Dans le fichier cron_job.sh:
#!/bin/bash
source $HOME/.bash_profile
some_other_cmd
Toute commande après la source de .bash_profile aura votre environnement comme si vous vous êtes connecté.
Si vous démarrez les scripts que vous exécutez par Cron avec:
#!/bin/bash -l
Ils devraient chercher vos variables d'environnement ~/.bash_profile
Pour moi, je devais définir la variable d'environnement pour une application php. Je resloved en ajoutant le code suivant à mon crontab.
$ sudo crontab -e
crontab:
ENVIRONMENT_VAR=production
* * * * * /home/deploy/my_app/cron/cron.doSomethingWonderful.php
et à l'intérieur doSomethingWonderful.php je pouvais obtenir la valeur de l'environnement avec:
<?php
echo $_SERVER['ENVIRONMENT_VAR']; # => "production"
J'espère que cela aide!
Tout ce que vous définissez dans crontab
sera disponible dans les cronjobs, à la fois directement et en utilisant les variables dans les scripts.
Utilisez-les dans la définition de la tâche cron
Vous pouvez configurer crontab
afin qu'il fixe des variables qui peuvent alors l'utiliser Cron:
$ crontab -l
myvar="hi man"
* * * * * echo "$myvar. date is $(date)" >> /tmp/hello
Maintenant, le fichier /tmp/hello
montre des choses comme:
$ 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
Utilisez-les dans le script exécuté par cronjob
Vous pouvez configurer crontab
afin qu'il fixe des variables qui alors les scripts peuvent utiliser:
$ crontab -l
myvar="hi man"
* * * * * /bin/bash /tmp/myscript.sh
Et dire est comme /tmp/myscript.sh
script ceci:
echo "Now is $(date). myvar=$myvar" >> /tmp/myoutput.res
Il génère une projection de /tmp/myoutput.res
de fichier:
$ 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
...
Au lieu de
0 * * * * sh /my/script.sh
Utilisez bash -l -c
0 * * * * bash -l -c 'sh /my/script.sh'
L'expansion sur Brisita a expansion @ Robert vient, même si vous ne voulez pas mettre en place toutes les variables du profil dans le script, vous pouvez sélectionner les variables à exporter sur le haut du script
Dans crontab -e fichier:
SHELL=/bin/bash
*/1 * * * * /Path/to/script/script.sh
Dans script.sh
#!/bin/bash
export JAVA_HOME=/path/to/jdk
some-other-command
Une autre façon - inspirée par cette cette réponse - aux variables "injecter" est le suivant (fcron exemple):
%daily 00 12 \
set -a; \
. /path/to/file/containing/vars; \
set +a; \
/path/to/script/using/vars
De help set
:
-a des variables qui sont modifiées Marquer ou créées pour l'exportation.
Utilisation + plutôt que -. Causes de ces drapeaux pour être désactivé
Alors tout le reste set -
et set +
s'exportés vers env
et est alors disponible pour d'autres scripts, etc. Sans utiliser set
les variables sont remplacées, mais vivent dans sourced set
seulement.
En dehors de cela, il est également utile de passer des variables lorsqu'un programme nécessite un compte non root pour exécuter, mais vous auriez besoin de quelques variables dans l'environnement de l'autre utilisateur. Ci-dessous un exemple passant nullmailer vars pour mettre en forme l'en-tête e-mail:
su -s /bin/bash -c "set -a; \
. /path/to/nullmailer-vars; \
set +a; \
/usr/sbin/logcheck" logcheck
J'ai essayé la plupart des solutions proposées, mais rien ne fonctionnait dans un premier temps. Il se trouve, cependant, que ce ne sont pas les solutions qui ont échoué au travail. Apparemment, mon fichier ~/.bashrc
commence par le bloc de code suivant:
case $- in
*i*) ;;
*) return;;
esac
Ceci est essentiellement un case statement
qui vérifie l'ensemble des options en cours dans le shell en cours pour déterminer que le shell est exécuté de manière interactive.
Si la coquille se trouve être en cours d'exécution de manière interactive, il passe à l'approvisionnement du fichier ~/.bashrc
.
Cependant, dans une coquille invoquée par cron
, la variable $-
ne contient pas la valeur i
qui indique l'interactivité.
Par conséquent, le fichier ~/.bashrc
ne se provient entièrement. Par conséquent, les variables d'environnement ne se sont fixés.
Si cela se trouve être votre problème, ne hésitez pas à commenter le bloc de code comme suit et essayez à nouveau:
# case $- in
# *i*) ;;
# *) return;;
# esac
J'espère que cela se révèle utile
J'utilise Oh-my-zsh
dans mon macbook, donc je l'ai essayé beaucoup de choses pour obtenir la tâche crontab fonctionne, mais finalement, ma solution était la préfixer .zshrc
avant la commande à exécuter.
*/30 * * * * . $HOME/.zshrc; node /path/for/my_script.js
Cette tâche toutes les 30 minutes et utilise le profil de .zshrc
pour exécuter ma commande noeud.
Ne pas oublier d'utiliser le point avant la $HOME
var.