Para demostrar el problema que tengo, usaré esta función simple, que se encuentra en /Users/X/Code/python/example/start.py :
def say_hello(name): print("Saying hello to {}".format(name)) say_hello("John") Estoy usando pipenv para configurar mis paquetes y mi entorno. En esta carpeta (al lado de start.py ), tengo otros cuatro archivos: Pipfile , Pipfile.lock , .env y log.txt .
Cuando ejecuto pipenv run python start.py , todo funciona bien y obtengo un resultado.
Ahora quiero que este script se ejecute cada minuto, así que configuré un trabajo cron usando crontab -e y esto es lo que inicialmente tenía allí:
* * * * * /usr/local/bin/pipenv run python /Users/X/Code/python/example/start.py >> /Users/X/Code/python/example/log.txt 2>&1
Lo que me estaba dando un volcado de error en ese archivo log.txt :
RuntimeError: Click will abort further execution because Python 3 was configured to use ASCII as encoding for the environment. Consult http://click.pocoo.org/python3/for mitigation steps. This system lists a couple of UTF-8 supporting locales that you can pick from. The following suitable locales where discovered: af_ZA.UTF-8, am_ET.UTF-8, be_BY.UTF-8, bg_BG.UTF-8, ca_ES.UTF-8, cs_CZ.UTF-8, da_DK.UTF-8, de_AT.UTF-8, de_CH.UTF-8, de_DE.UTF-8, el_GR.UTF-8, en_AU.UTF-8.... Después de una buena cantidad de búsqueda en Google, llegué a la conclusión de que el entorno no estaba configurando las configuraciones locales correctas, por lo que agregué ese archivo .env que se ve así:
LC_ALL=en_GB.UTF-8 LANG=en_GB.UTF-8 Luego pasé unos minutos más mirando el mismo error que aparecía en log.txt una y otra vez y luego me di cuenta de que cuando llamo a /usr/local/bin/pipenv , en realidad necesita el Pipfile correcto para cargar el entorno correcto . Entonces, en cambio, cambié mi cron a esto:
* * * * * cd /Users/X/Code/python/example && /usr/local/bin/pipenv run python /Users/X/Code/python/example/start.py >> /Users/X/Code/python/example/log.txt 2>&1 Entonces, técnicamente, ahora debería estar ingresando a la carpeta con un cd y LUEGO ejecutando las cosas de pipenv , pero sigo recibiendo exactamente el mismo error en mi archivo de log .
Cualquier ayuda sería muy apreciada.
Intente agregar /usr/local/bin a su PATH también. Parece que pipenv puede necesitar llamar a otras aplicaciones en la ruta donde también se encuentra. Cuando cron ejecuta trabajos, no tiene el mismo entorno que obtiene cuando inicia sesión en un shell.
Probablemente sea más fácil crear un script contenedor para llamar desde cron:
cd /Users/X/Code/python/example PATH=/usr/local/bin:$PATH pipenv run python start.py >> /Users/X/Code/python/example/log.txt 2>&1Recientemente tuve este problema con un programa de python que usaba pexpect y se ejecutaba a través de cron. Como otros mencionaron, cron no tiene el mismo entorno, es decir, $ PATH que el usuario que ingresa los datos del script cron. En mi caso, estoy usando un entorno redhat que también tiene una colección de software que proporciona python3.6 (como se menciona en esta publicación redhat-py3 ).
De todos modos, mi solución al enigma pipenv - cron fue usar penv para crear virtualenv con las dependencias requeridas. Y luego use 'pipenv shell' para obtener un comando de shell que podría usarse para activar virtualenv a través de cron y bash. Si ya instalé mis dependencias con pipenv y creé un Pipfile, entonces puedo verificar virtualenv usando
pipenv checkSi ya tengo un virtualenv, veré los siguientes mensajes.
Checking PEP 508 requirements… Passed! Checking installed package safety… All good!Entonces puedo ejecutar el shell pipenv
pipenv shellLo cual debe resultar en lo siguiente
Launching subshell in virtual environment… . /<path>/<to>/<virtualenv>/bin/activate!!!Observe el punto "." en la segunda línea de la salida esperada. Esta línea se puede colocar en mi secuencia de comandos cron (recomiendo una secuencia de comandos de Shell). Que luego es llamado por cron.
El guión final ejecutado por cron y tomado de @Chris Shaw se vería así:
#!/bin/bash #or whatever shell you use cd /Users/X/Code/python/example . /<path>/<to>/<virtualenv>/bin/activate # you should specifiy the python version in the below command #python2.7 start.py >> /Users/X/Code/python/example/log.txt 2>&1 python3 start.py >> /Users/X/Code/python/example/log.txt 2>&1Esta solución es frágil, debido a la dependencia de un virtualenv específico, en lugar de los comandos pipenv. Entonces, si recrea el virtualenv, es probable que resulte en una nueva ruta. Que deberá actualizarse en su script de shell. Pero elimina la dependencia de pipenv para proporcionar el entorno de shell para cron.
Como nota adicional, sugiero agregar una alerta por correo electrónico o algo similar si el trabajo cron comienza a fallar. Por lo general, Cron falla silenciosamente y felizmente continuará sin hacer lo que quiere hasta que descubra la falla.
Para mí, ha sido suficiente ejecutar directamente el ejecutable Python de virtualenv, por ejemplo:
0 5 * * * /home/user/.local/share/virtualenvs/project-30iXwYpI/bin/python /home/user/project/script.pyComo ha señalado wordtronix, puede obtener la ubicación de su virtualenv ejecutando pipenv y viendo lo que imprime en la consola.