Normalmente tengo varios problemas con la forma en que cron ejecuta los scripts ya que normalmente no tienen la configuración de mi entorno. ¿Hay alguna manera de invocar bash (?) De la misma forma que lo hace cron para poder probar los scripts antes de instalarlos?
Agrega esto a tu cron:
30 08 * * * env > ~/cronenv
Después de que se ejecute, haz esto:
env - `cat ~/cronenv` /bin/sh
Esto supone que su cron ejecuta / bin / sh, que es el predeterminado independientemente del shell predeterminado del usuario.
Cron solo proporciona este entorno por defecto:
HOME
LOGNAME
usuario de LOGNAME
PATH=/usr/bin:/usr/sbin
SHELL=/usr/bin/sh
Si necesita más, puede generar un script donde defina su entorno antes de la tabla de progtwigción en el crontab.
Par de enfoques:
Exporte cron env y source it:
Añadir
* * * * * env > ~/cronenv
a su crontab, déjelo funcionar una vez, apáguelo, luego ejecútelo
env - `cat ~/cronenv` /bin/sh
Y ahora estás dentro de una sesión sh
que tiene el entorno de cron
Trae tu entorno a cron
Puede omitir el ejercicio anterior y simplemente hacer a . ~/.profile
. ~/.profile
en frente de su trabajo cron, por ejemplo
* * * * * . ~/.profile; your_command
Usar la pantalla
Las dos soluciones anteriores todavía fallan porque proporcionan un entorno conectado a una sesión X en ejecución, con acceso a dbus
etc. Por ejemplo, en Ubuntu, nmcli
(Network Manager) funcionará en los dos enfoques anteriores, pero aún falla en cron.
* * * * * /usr/bin/screen -dm
Agregue la línea anterior a cron, permita que se ejecute una vez, desactívela. Conéctese a su sesión de pantalla (pantalla -r). Si está comprobando que la sesión de la pantalla ha sido creada (con ps
) tenga en cuenta que a veces están en mayúsculas (por ejemplo, ps | grep SCREEN
)
Ahora incluso nmcli
y similar fallarán.
Tu puedes correr:
env - your_command arguments
Esto ejecutará tu_comando con un entorno vacío.
Dependiendo del shell de la cuenta
sudo su env -i /bin/sh
o
sudo su env -i /bin/bash --noprofile --norc
De http://matthew.mceachen.us/blog/howto-simulate-the-cron-environment-1018.html
Respondiendo seis años después: el problema de desajuste del entorno es uno de los problemas resueltos por los “temporizadores” del sistema como un reemplazo de cron. Ya sea que ejecute el “servicio” systemd desde la CLI o vía cron, recibe exactamente el mismo entorno, evitando el problema de desajuste del entorno.
El problema más común para hacer que las tareas cron fallen cuando se pasan manualmente es el valor predeterminado $PATH
establecido por cron, que es esto en Ubuntu 16.04:
"/usr/bin:/bin"
Por el contrario, el valor predeterminado $PATH
establecido por systemd
en Ubuntu 16.04 es:
"/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
Por lo tanto, existe una mayor probabilidad de que un temporizador systemd encuentre un binario sin complicaciones adicionales.
La desventaja de los temporizadores systemd es que hay un poco más de tiempo para configurarlos. Primero crea un archivo de “servicio” para definir lo que quiere ejecutar y un archivo de “temporizador” para definir el cronogtwig para ejecutarlo y finalmente “habilitar” el temporizador para activarlo.
Cree un trabajo cron que ejecute env y redireccione stdout a un archivo. Use el archivo junto a “env -” para crear el mismo entorno que un trabajo cron.
No olvide que como el padre de cron es init, ejecuta progtwigs sin un terminal de control. Puedes simular eso con una herramienta como esta:
De forma predeterminada, cron
ejecuta sus trabajos utilizando la idea que tenga su sistema de sh
. Este podría ser el shell Bourne real o dash
, ash
, ksh
o bash
(u otro) enlazado a sh
(y como resultado ejecutándose en modo POSIX).
Lo mejor que puedes hacer es asegurarte de que tus scripts tengan lo que necesitan y asumir que no se les proporciona nada. Por lo tanto, debe usar las especificaciones de directorio completo y establecer variables de entorno como $PATH
usted mismo.
Otra forma simple que he encontrado (pero puede ser propensa a errores, todavía estoy probando) es obtener los archivos de perfil de tu usuario antes de tu comando.
Editando un script /etc/cron.d/:
* * * * * user1 comand-that-needs-env-vars
Se convertiría en:
* * * * * user1 source ~/.bash_profile; source ~/.bashrc; comand-that-needs-env-vars
Sucio, pero hizo el trabajo por mí. ¿Hay alguna forma de simular un inicio de sesión? ¿Solo un comando que podrías ejecutar? bash --login
no funcionó. Parece que esa sería la mejor manera de hacerlo.
EDITAR: Esta parece ser una solución sólida: http://www.epicserve.com/blog/2012/feb/7/my-notes-cron-directory-etccrond-ubuntu-1110/
* * * * * root su --session-command="comand-that-needs-env-vars" user1 -l
La respuesta https://stackoverflow.com/a/2546509/5593430 muestra cómo obtener el entorno cron y usarlo para su script. Pero tenga en cuenta que el entorno puede diferir dependiendo del archivo crontab que use. Creé tres entradas cron diferentes para guardar el entorno a través de env > log
. Estos son los resultados en Amazon Linux 4.4.35-33.55.amzn1.x86_64.
MAILTO=root SHELL=/bin/bash USER=root PATH=/sbin:/bin:/usr/sbin:/usr/bin PWD=/ LANG=en_US.UTF-8 SHLVL=1 HOME=/ LOGNAME=root _=/bin/env
crontab -e
) SHELL=/bin/sh USER=root PATH=/usr/bin:/bin PWD=/root LANG=en_US.UTF-8 SHLVL=1 HOME=/root LOGNAME=root _=/usr/bin/env
MAILTO=root SHELL=/bin/bash USER=root PATH=/sbin:/bin:/usr/sbin:/usr/bin _=/bin/env PWD=/ LANG=en_US.UTF-8 SHLVL=3 HOME=/ LOGNAME=root
Lo más importante es que PATH
, PWD
y HOME
difieren. Asegúrese de configurarlos en sus scripts cron para confiar en un entorno estable.
No creo que exista; la única forma que conozco de probar un trabajo cron es configurarlo para que se ejecute uno o dos minutos en el futuro y luego esperar.