¿Dónde puedo establecer variables de entorno que se utilice crontab?
-
19-09-2019 - |
Pregunta
Tengo un crontab que sale cada hora. El usuario que ejecuta tiene variabless entorno en el .bash_profile
que funciona cuando el usuario ejecuta el trabajo de la terminal, sin embargo, obviamente, estos no son recogidas por crontab cuando se ejecuta.
He intentado fijar en ellas .profile
y .bashrc
pero todavía no parecen ser recogido. ¿Alguien sabe donde puedo poner ambiente vars que crontab puede recoger?
Solución
Tienes 'cron' ejecutar un script de shell que establece 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 los enlaces a una única secuencia de comandos, 'runcron', que se parece a:
: "$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 utilizando un estándar de codificación de más edad -. Hoy en día, que haría uso de un tinglado '! #' Al inicio)
El '~ / .cronfile' es una variación del perfil para su uso por cron - rigurosamente no interactivo y ningún eco en aras de ser ruidoso. Se podría disponer para ejecutar el .profile y así sucesivamente en su lugar. (Las cosas REAL_HOME es un artefacto de mi entorno -. Se puede pretender que es lo mismo que $ HOME)
Por lo tanto, este código lee el ambiente apropiado y luego ejecuta la versión no Cron del comando de mi directorio personal. Así, por ejemplo, mi comando 'día de la semana' se parece a:
: "@(#)$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 'diaria' 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
Otros consejos
Se pueden definir variables de entorno en el propio crontab cuando se ejecuta crontab -e
desde la línea de comandos.
LANG=nb_NO.UTF-8
LC_ALL=nb_NO.UTF-8
# m h dom mon dow command
* * * * * sleep 5s && echo "yo"
Esta función sólo está disponible para ciertas implementaciones de cron. Ubuntu y Debian actualmente usan vixie-cron que permite que éstos sean declaradas en el archivo crontab (también GNU mcron ).
Archlinux y RedHat usar Cronie que ¿no permiten variables de entorno para ser declaradas y arrojará errores de sintaxis en el cron.log. Solución alternativa se puede hacer por entrada:
# m h 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 se recogerá toda la variable de entorno se define en el archivo de $HOME/.profile
.
Por supuesto $HOME
tampoco se establece, hay que sustituirla por la ruta completa de su $HOME
.
Configuración de Vars en /etc/environment
también trabajó para mí en Ubuntu. A partir de 12,04, variables en /etc/environment
se cargan para cron.
Ampliando ejemplo @carestad, que me parece más fácil, es ejecutar el script con cron y tener el entorno en el guión.
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 después de que la fuente de .bash_profile tendrá su entorno como si inició la sesión.
Si comienza a las secuencias de comandos que se ejecutan a través de cron con:
#!/bin/bash -l
Deben recoger las variables de entorno ~/.bash_profile
Para mí que tenía que establecer la variable de entorno para una aplicación PHP. Me resloved añadiendo el siguiente código a mi crontab.
$ sudo crontab -e
crontab:
ENVIRONMENT_VAR=production
* * * * * /home/deploy/my_app/cron/cron.doSomethingWonderful.php
y en el interior doSomethingWonderful.php que podría conseguir el valor medio con:
<?php
echo $_SERVER['ENVIRONMENT_VAR']; # => "production"
Espero que esto ayude!
Lo que se establece en crontab
estará disponible en los cronjobs, tanto directamente como mediante las variables en las secuencias de comandos.
utilizarlos en la definición de la tarea programada
Puede configurar crontab
hasta que se cuaje variables que pueden entonces la tarea programada uso:
$ crontab -l
myvar="hi man"
* * * * * echo "$myvar. date is $(date)" >> /tmp/hello
Ahora el /tmp/hello
archivo 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
Úsalos en la secuencia de comandos ejecutada por cron
Puede configurar crontab
hasta que se cuaje variables que a continuación, los scripts pueden utilizar:
$ crontab -l
myvar="hi man"
* * * * * /bin/bash /tmp/myscript.sh
Y decir /tmp/myscript.sh
guión es como sigue:
echo "Now is $(date). myvar=$myvar" >> /tmp/myoutput.res
Se genera un archivo que muestra /tmp/myoutput.res
:
$ 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
...
En lugar de
0 * * * * sh /my/script.sh
Utilice fiesta -l -c
0 * * * * bash -l -c 'sh /my/script.sh'
Ampliando @ Robert brisita acaba de ampliar, también si no desea configurar todas las variables del perfil en el guión, puede seleccionar las variables a exportar en la parte superior de la secuencia de comandos
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
Otra manera - inspirado por esta esta respuesta - "inyectar" variables es la siguiente (fcron ejemplo):
%daily 00 12 \
set -a; \
. /path/to/file/containing/vars; \
set +a; \
/path/to/script/using/vars
De help set
:
-a variables de marca que están modificados o creados para la exportación.
Uso + en lugar de -. Hace que estas banderas que se desactive
Así que todo en el medio set -
y set +
se exporta a env
y está entonces disponible para otros scripts, etc. Sin utilizar set
las variables consiguen provienen, pero viven en set
solamente.
Aparte de eso también es útil para pasar variables cuando un programa requiere una cuenta sin privilegios de correr, pero se necesitaría algunas variables dentro del entorno de ese otro usuario. A continuación se muestra un ejemplo en el que pasa nullmailer vars para dar formato al encabezado de correo electrónico:
su -s /bin/bash -c "set -a; \
. /path/to/nullmailer-vars; \
set +a; \
/usr/sbin/logcheck" logcheck
Probé la mayoría de las soluciones aportadas, pero nada funcionó al principio. Resulta, sin embargo, que no era las soluciones que no pudieron trabajar. Al parecer, mi archivo ~/.bashrc
comienza con el siguiente bloque de código:
case $- in
*i*) ;;
*) return;;
esac
Esto básicamente es un case statement
que comprueba el conjunto actual de opciones en el shell actual para determinar que la cáscara se está ejecutando de forma interactiva.
Si la cáscara se esté ejecutando de forma interactiva, a continuación, se pasa al abastecimiento del archivo ~/.bashrc
.
Sin embargo, en una cáscara invocada por cron
, la variable $-
no contiene el valor i
que indica la interactividad.
Por lo tanto, el archivo de origen ~/.bashrc
nunca consigue plenamente. Como resultado, las variables de entorno no segregaba.
Si esto pasa a ser el problema, no dude en comentar a cabo el bloque de código como sigue y vuelve a intentarlo:
# case $- in
# *i*) ;;
# *) return;;
# esac
Espero que esto resulta útil
Estoy usando Oh-my-zsh
en mi macbook así que he intentado muchas cosas para conseguir la tarea se ejecuta crontab pero finalmente, mi solución estaba prepending la .zshrc
antes de que el comando a ejecutar.
*/30 * * * * . $HOME/.zshrc; node /path/for/my_script.js
Esta tarea se ejecuta cada 30 minutos y utiliza el perfil .zshrc
para ejecutar mi mando nodo.
No se olvide de utilizar el punto antes de la $HOME
var.