J'ai une crontab en marche toutes les heures. L'utilisateur qui l'exécute a un environnement variable dans le .bash_profile
qui fonctionne lorsque l'utilisateur exécute le travail à partir du terminal. Toutefois, il est évident que ceux-ci ne sont pas récupérés par crontab lors de son exécution.
J'ai essayé de les placer dans .profile
et .bashrc
mais ils ne semblent toujours pas avoir été captés. Est-ce que quelqu'un sait où je peux mettre les vars d'environnement que crontab peut prendre?
Demandez à 'cron' d'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 des 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 ancienne norme de codage - de nos jours, j'utiliserais un Shebang '#!' Au début.)
Le fichier "~/.cronfile" est une variante de mon profil destinée à être utilisée par cron - rigoureusement non interactif et ne faisant pas écho pour être bruyant. Vous pouvez organiser à la place le fichier .profile, etc. (Le contenu de REAL_HOME est un artefact de mon environnement - vous pouvez prétendre qu'il en va de même pour $ HOME.)
Ainsi, ce code lit l'environnement approprié, puis exécute la version non cron de la commande à partir de mon répertoire personnel. Ainsi, par exemple, ma commande "jour de la semaine" ressemble à ceci:
: "@(#)$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 'daily' 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
Vous pouvez définir des variables d'environnement dans la crontab elle-même lors de l'exécution de crontab -e
à partir 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é n'est disponible que pour certaines implémentations de cron. Ubuntu et Debian utilisent actuellement vixie-cron , ce qui permet de les déclarer dans le fichier crontab (également GNU mcron ).
Archlinux et RedHat utilise cronie qui n'autorise pas les variables d'environnement. à déclarer et jettera des erreurs de syntaxe dans le fichier cron.log. La solution de contournement peut être effectuée par entrée:
# m h dom mon dow command
* * * * * export LC_ALL=nb_NO.UTF-8; sleep 5s && echo "yo"
J'ai encore une solution à ce problème:
0 5 * * * . $HOME/.profile; /path/to/command/to/run
Dans ce cas, toutes les variables d’environnement définies dans votre fichier $HOME/.profile
seront sélectionnées.
Bien sûr, $HOME
n'est pas défini, vous devez le remplacer par le chemin complet de votre $HOME
.
La définition de vars dans /etc/environment
a également fonctionné pour moi dans Ubuntu. A partir de 12.04, les variables dans /etc/environment
sont chargées pour cron.
L’exemple @carestad, que je trouve plus facile, consiste à exécuter le script avec cron et à inclure l’environnement dans le script.
Dans le fichier crontab -e:
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 étiez connecté.
Si vous démarrez les scripts que vous exécutez via cron avec:
#!/bin/bash -l
Ils devraient récupérer vos variables d’environnement ~/.bash_profile
Pour moi, je devais définir la variable d'environnement pour une application PHP. Je l'ai aimé en ajoutant le code suivant à ma crontab.
$ Sudo crontab -e
crontab:
ENVIRONMENT_VAR=production
* * * * * /home/deploy/my_app/cron/cron.doSomethingWonderful.php
et dans doSomethingWonderful.php, je pourrais obtenir la valeur d'environnement avec:
<?php
echo $_SERVER['ENVIRONMENT_VAR']; # => "production"
J'espère que ça aide!
Tout ce que vous définissez dans crontab
sera disponible dans les tâches cron, à la fois directement et en utilisant les variables dans les scripts.
Vous pouvez configurer crontab
pour qu'il définisse des variables qui seront ensuite utilisées par cronjob:
$ 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
Vous pouvez configurer crontab
pour qu'il définisse des variables que les scripts peuvent ensuite utiliser:
$ crontab -l
myvar="hi man"
* * * * * /bin/bash /tmp/myscript.sh
Et dites script /tmp/myscript.sh
est comme ceci:
echo "Now is $(date). myvar=$myvar" >> /tmp/myoutput.res
Il génère un fichier /tmp/myoutput.res
montrant:
$ 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'
Développer @Robert Brisita vient de se développer. Si vous ne souhaitez pas configurer toutes les variables du profil dans le script, vous pouvez sélectionner les variables à exporter en haut du script.
Dans le fichier crontab -e:
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 manière - inspirée par ceci cette réponse - d’injecter des variables est la suivante (exemple fcron):
%daily 00 12 \
set -a; \
. /path/to/file/containing/vars; \
set +a; \
/path/to/script/using/vars
De help set
:
-a Marque les variables qui sont modifiées ou créées pour l'exportation.
L'utilisation de + plutôt que de - désactive ces indicateurs.
Ainsi, tout ce qui se trouve entre set -
et set +
est exporté vers env
et est ensuite disponible pour d'autres scripts, etc. Sans utiliser set
, les variables sont recherchées mais résident dans set
seulement.
En dehors de cela, il est également utile de passer des variables lorsqu'un programme nécessite l'exécution d'un compte non-root mais que vous avez besoin de certaines variables dans l'environnement de cet autre utilisateur. Voici un exemple en passant à nullmailer vars pour formater l'en-tête de courrier électronique:
su -s /bin/bash -c "set -a; \
. /path/to/nullmailer-vars; \
set +a; \
/usr/sbin/logcheck" logcheck
J'ai essayé la plupart des solutions fournies, mais rien n'a fonctionné au début. Il s'avère toutefois que ce ne sont pas les solutions qui ont échoué. Apparemment, mon fichier ~/.bashrc
commence par le bloc de code suivant:
case $- in
*i*) ;;
*) return;;
esac
Il s'agit essentiellement d'un case statement
qui vérifie le jeu d'options actuel dans le shell actuel pour déterminer que celui-ci s'exécute de manière interactive. Si le shell s'exécute de manière interactive, il passe ensuite à la recherche du fichier ~/.bashrc
. Cependant, dans un Shell appelé par cron
, la variable $-
ne contient pas la valeur i
qui indique une interactivité. Par conséquent, le fichier ~/.bashrc
ne sera jamais entièrement source. En conséquence, les variables d'environnement ne sont jamais définies. Si cela vous pose problème, n'hésitez pas à commenter le bloc de code comme suit et essayez à nouveau:
# case $- in
# *i*) ;;
# *) return;;
# esac
J'espère que cela s'avère utile
J'utilise Oh-my-zsh
dans mon macbook. J'ai donc essayé beaucoup de choses pour que la tâche crontab s'exécute, mais finalement, ma solution préfigurait le .zshrc
avant l'exécution de la commande.
*/30 * * * * . $HOME/.zshrc; node /path/for/my_script.js
Cette tâche s'exécute toutes les 30 minutes et utilise le profil .zshrc
pour exécuter ma commande de nœud.
N'oubliez pas d'utiliser le point avant le $HOME
var.