¿Dónde puedo establecer las variables de entorno que usará crontab?

Tengo un crontab corriendo cada hora. El usuario que lo ejecuta tiene variables de entorno en .bash_profile que funcionan cuando el usuario ejecuta el trabajo desde el terminal, sin embargo, obviamente, crontab no lo detecta cuando se ejecuta.

Intenté configurarlos en .profile y .bashrc pero aún así no parecen ser recogidos. ¿Alguien sabe dónde puedo poner los valores ambientales que crontab puede recoger?

Haga que ‘cron’ ejecute un script de shell que configure el entorno antes de ejecutar el comando.

Siempre.

 # @(#)$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 

Los scripts en ~ / bin / Cron son todos enlaces a un solo script, ‘runcron’, que se ve así:

 : "$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 ${@:+"$@"} 

(Escrito usando un estándar de encoding anterior – hoy en día, ¡usaría un shebang ‘#!’ Al comienzo).

El ‘~ / .cronfile’ es una variación de mi perfil para uso cron – rigurosamente no interactivo y sin eco por el simple hecho de ser ruidoso. Podría organizar la ejecución del .profile y así sucesivamente. (Las cosas de REAL_HOME son un artefacto de mi entorno; puedes pretender que es lo mismo que $ HOME).

Entonces, este código lee el entorno apropiado y luego ejecuta la versión que no es Cron del comando desde mi directorio de inicio. Entonces, por ejemplo, mi comando ‘día de la semana’ se ve así:

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

El comando ‘diario’ es más 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 

Puede definir variables de entorno en el propio crontab al ejecutar crontab -e desde la línea de comando.

 LANG=nb_NO.UTF-8 LC_ALL=nb_NO.UTF-8 # mh dom mon dow command * * * * * sleep 5s && echo "yo" 

Esta función solo está disponible para ciertas implementaciones de cron. Ubuntu y Debian actualmente usan vixie-cron que permite que estos sean declarados en el archivo crontab (también GNU mcron ).

Archlinux y RedHat usan cronie que no permite declarar variables de entorno y arrojará errores de syntax en cron.log. La solución se puede hacer por entrada:

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

Tengo una solución más para este problema:

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

En este caso, elegirá todas las variables de entorno definidas en su archivo $ HOME / .profile.

Por supuesto, $ HOME tampoco está configurado, debe reemplazarlo con la ruta completa de su $ HOME.

Establecer vars en /etc/environment también me funcionó en Ubuntu. A partir del 12.04, las variables en / etc / environment se cargan para cron.

Expandir el ejemplo de @carestad, que me resulta más fácil, es ejecutar el script con cron y tener el entorno en el script.

En el archivo crontab -e:

 SHELL=/bin/bash */1 * * * * $HOME/cron_job.sh 

En el archivo cron_job.sh:

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

Cualquier comando posterior al origen de .bash_profile tendrá su entorno como si hubiera iniciado sesión.

Para mí tuve que establecer la variable de entorno para una aplicación php. Lo resuelvo agregando el siguiente código a mi crontab.

 $ sudo crontab -e 

crontab:

 ENVIRONMENT_VAR=production * * * * * /home/deploy/my_app/cron/cron.doSomethingWonderful.php 

y dentro de doSomethingWonderful.php podría obtener el valor del entorno con:

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

¡Espero que esto ayude!

Cualquier cosa que configure en crontab estará disponible en cronjobs, tanto directamente como usando las variables en los scripts.

Úselos en la definición del cronjob

Puede configurar crontab para que establezca las variables que luego utiliza el cronjob de lata:

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

Ahora el archivo /tmp/hello muestra cosas como:

 $ 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 

Úselos en el script ejecutado por cronjob

Puede configurar crontab para que establezca las variables que luego pueden usar los scripts:

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

Y dicen que el script /tmp/myscript.sh es así:

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

Genera un archivo /tmp/myoutput.res muestra:

 $ 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 ... 

La expansión en @Robert Brisita se acaba de expandir, también si no desea configurar todas las variables del perfil en el script, puede seleccionar las variables para exportar en la parte superior del script

En el archivo crontab -e:

 SHELL=/bin/bash */1 * * * * /Path/to/script/script.sh 

En script.sh

 #!/bin/bash export JAVA_HOME=/path/to/jdk some-other-command 

En lugar de

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

Usa bash -l -c

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

Otra forma – inspirada por esta esta respuesta – para “inyectar” variables es la siguiente (ejemplo fcron):

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

Del help set :

-a Marca las variables que se modifican o crean para exportar.

Usar + en lugar de – hace que estos indicadores se apaguen.

Entonces, todo lo que está entre set - y set + se exporta a env y luego está disponible para otras secuencias de comandos, etc. Sin usar set las variables se obtienen de fonts, pero viven en set solamente.

Aparte de eso, también es útil pasar variables cuando un progtwig requiere que se ejecute una cuenta que no sea de root, pero necesita algunas variables dentro del entorno de ese otro usuario. A continuación se muestra un ejemplo que pasa en nullmailer vars para formatear el encabezado del correo electrónico:

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

Si inicia los scripts que está ejecutando a través de cron con:

#!/bin/bash -l

Deberían recoger sus variables de entorno ~ / .bash_profile

Probé la mayoría de las soluciones proporcionadas, pero nada funcionó al principio. Sin embargo, resulta que no fueron las soluciones las que no funcionaron. Aparentemente, mi archivo ~/.bashrc comienza con el siguiente bloque de código:

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

Básicamente, se trata de una case statement que verifica el conjunto actual de opciones en el shell actual para determinar que el shell se ejecuta de forma interactiva. Si el shell se ejecuta de forma interactiva, pasa al origen del archivo ~/.bashrc . Sin embargo, en un shell invocado por cron , la variable $- no contiene el valor i que indica interactividad. Por lo tanto, el archivo ~/.bashrc nunca se obtiene por completo. Como resultado, las variables de entorno nunca se configuraron. Si este es su problema, no dude en comentar el bloque de código de la siguiente manera y vuelva a intentarlo:

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

Espero que esto resulte útil