Saltar al contenido

ejecutar un trabajo crontab usando un entorno anaconda

Solución:

Recientemente cambié de canopy a Anaconda precisamente para evitar tener que activar un env en trabajos cron. Anaconda lo hace muy simple, basado en la variable de entorno PATH. (Estoy usando miniconda, no la instalación completa de Anaconds, pero creo que anaconda debería funcionar de la misma manera)

Hay dos enfoques diferentes que he probado;

  • Agregue un shebang en su script de Python, main.py

    #!/home/users/user_name/miniconda2/envs/my_env/bin/python

  • Agregue PATH a la parte superior de su crontab

    PATH=/home/users/user_name/miniconda2/envs/my_env/bin

Actualizar:

La respuesta de Jérôme y los comentarios de cbarrick son correctos. Acabo de quemarme usando el enfoque anterior en un Conda env que necesitaba pynco, que necesita el entorno completo de conda para encontrar el nco comandos, como ncks, ncrcat. Resuelto ejecutando un script bash desde cron que llama a conda activo primero.

No llames sh pero bash. source es un comando bash.

- sh scripts/my_script.bash
+ bash scripts/my_script.bash

O solo

chmod +x scripts/my_script.bash
./scripts/my_script.bash

desde que agregaste el bash shebang.

Después de MUCHO violín conseguí crontab para activar mi entorno conda con conda activate my_env y ejecute el intérprete de Python dentro de ese entorno.

Tenga en cuenta que estoy usando Ubuntu 18.04.

Fondo

  • Cuando el instalador de Anaconda inicializa conda, agrega un fragmento al final del ~/.bashrc expediente. Este archivo se ejecuta cada vez que el usuario abre bash interactivamente. El fragmento permite al usuario ejecutar conda comandos (es decir conda activate my_env) de bash.

  • El instalador de Anaconda v2020.02 agregó lo siguiente conda fragmento en ~/.bashrc:

# >>> conda initialize >>>
# !! Contents within this block are managed by 'conda init' !!
__conda_setup="$('/opt/anaconda3/bin/conda' 'shell.bash' 'hook' 2> /dev/null)"
if [ $? -eq 0 ]; then
    eval "$__conda_setup"
else
    if [ -f "/opt/anaconda3/etc/profile.d/conda.sh" ]; then
        . "/opt/anaconda3/etc/profile.d/conda.sh"
    else
        export PATH="/opt/anaconda3/bin:$PATH"
    fi
fi
unset __conda_setup
# <<< conda initialize <<<
  • El camino /opt/anaconda3/ para ser reemplazado con la referencia correcta: generalmente /home/USERNAME/anaconda3/.

El problema

Abastecimiento ~/.bashrc en crontab -e no funcionará (al menos no en Ubuntu).

Explicación:

  • En Ubuntu, ~/.bashrc tiene la siguiente línea (o similar) al principio del archivo:
# If not running interactively, don't do anything
[ -z "$PS1" ] && return
  • Esto significa que si intentamos obtener el ~/.bashrc presentar en crontab, el resto de .bashrc el archivo no se ejecutará porque crontab no se ejecuta de forma interactiva (consulte otra publicación sobre este tema). Lo que significa que el conda el fragmento mencionado anteriormente nunca será ejecutado por crontab incluso si obtenemos ~/.bashrc.

_________ Solución de trabajo _________

La solución que he encontrado es copiar el conda fragmento en un archivo separado.

1. Copiar el conda fragmento de ~/.bashrc para ~/.bashrc_conda

Copie el fragmento mencionado anteriormente en otro archivo, por ejemplo ~/.bashrc_conda.

Asegurarse de que:

  • El usuario que ejecuta el cronjob tiene permiso para leer este archivo.
  • Otros usuarios no pueden escribir en este archivo (riesgo de seguridad).

2. En crontab -e inserte 2 líneas para ejecutar bash en lugar de sh y a la fuente ~/.bashrc_conda

Correr crontab -e y agregue las siguientes 2 líneas antes del cronjob:

SHELL=/bin/bash
BASH_ENV=~/.bashrc_conda

Explicación:

  • SHELL=/bin/bash significa que crontab ejecutará los cronjobs a través de bash en lugar de sh (defecto). Ver publicación.

  • BASH_ENV=~/.bashrc_conda fuentes el conda fragmento de bash contener chrontab. Ver publicación y publicación.

3 en crontab -e insertar en la línea cronjob conda activate my_env; antes de lo deseado .py ejecución de script

Ejemplo de entrada para un script que se ejecutaría al mediodía a las 12:30 todos los días dentro del entorno de conda deseado:

30 12 * * * conda activate my_env; python /path/to/script.py

Aviso conda activate my_env; antes del comando para ejecutar el intérprete de Python.

_______________

Y voilà, funcionó.

¿Algún inconveniente?

Si el conda fragmento en .bashrc se actualiza por un conda actualización, por supuesto, no se reflejará en la .bashrc_conda expediente. Es posible que deba buscar actualizaciones de vez en cuando.

También se podría agregar ; conda deactivate en el fin de ese cronjob, pero esto puede ser redundante.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *