Llevo varios días con este tema y finalmente he dado con la solución. El problema es que ruby necesita de un entorno de ejecución, que es automático cuando se ejecuta desde la línea de comandos, pero que no se carga cuando se ejecuta desde cron.
Cosas que intenté:
- Modificar el script ruby incluyendo las rutas hacia las gems usadas
- Ejecutar el script ruby desde un script de shell que incluía todas las variables de entorno necesarias
- Usar los ficheros de entorno RVM en un script de shell
- Usar llamadas directas a los wrappers generados por RVM
La solución que funcionó bien fue la última, la de los wrappers de RVM, pero antes de describirla, algunas cosas útiles que también utilicé y conviene mencionar:
- Al crear la tarea cron, conviene guardar los resultados en un fichero de log para saber lo que está ocurriendo, de este modo:
/ruta/hacia/ruby /ruta/hacia/script.rb >> /ruta/hacia/fichero.log
- Imprescindible redirigir cualquier error de ruby también hacia el fichero de log, así: (explicación aquí)
/ruta/hacia/ruby /ruta/hacia/script.rb >> /ruta/hacia/fichero.log 2>&1
- Saber que en Ubuntu, el log de la ejecución de cron se guarda en:
/var/log/syslog
aunque este es un log general, por lo que para ver líneas relacionadas con cron bastará con hacer un grep tipo:
grep CRON /var/log/syslog
- Es importante que el script .rb tenga permisos de ejecución, sino aunque lo puedas ejecutar manualmente por consola, cron no podrá hacerlo. Por lo tanto:
chmod 755 script.rb
Solución:
Dado que la solución está basada en RVM, evidentemente necesitamos tenerlo instalado (si no sabes lo que es, o no sabes cómo instalarlo, más información aquí).
Básicamente lo que hice fue llamar a ruby con el wrapper por defecto que RVM genera para la instalación global, sin embargo se puede crear un wrapper diferente con diferentes versiones de Ruby o de las gems que necesitemos. Como no soy experto en RVM y a mí en este caso me es suficiente con la instalación por defecto, reemplacé mi línea de crontab por esta:
0 1 * * * /usr/local/rvm/wrappers/ruby-1.9.3-p547/ruby /home/scripts/script.rb >> /home/scripts/script.log 2>&1
La carpeta /usr/local/rvm/wrappers/ruby-1.9.3-p547 es la de la distribución de ruby por defecto en mi sistema, pero debes adecuarla a tu instalación.
Después de varios días atascado viendo un fichero de log vacío o con errores de importación, ver el resultado esperado fue liberador. Espero haberte ahorrado algunas horas de vida, no las malgastes! 😉
Comment