¿Cómo simular el entorno con el que cron ejecuta un script?

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:

  • Directorio de inicio del usuario de 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:

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

  2. 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 
  3. 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:

http://libslack.org/daemon/

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.

1. Global / etc / crontab con usuario root

 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 

2. Usuario crontab de root ( 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 

3. Script en /etc/cron.hourly/

 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.