miércoles, 12 de febrero de 2020

Script se ejecuta en terminal pero no desde cron



Cómo hacer que un script que se ejecuta en terminal pero no desde crontab se ejecute.



Creas un script en bash. Lo ejecutas y funciona correctamente. Programas su ejecución periódica usando cron y cuando llega el momento de su primera ejecución, el script no se ejecuta. O, dicho de otra forma, sí se ejecuta pero no hace lo que tiene que hacer.

¿Qué ocurre?

El causante de que un script no se ejecute correctamente cuando es llamado desde cron puede variar, pero normalmente el problema reside en las variables de entorno. Más concretamente, en la variable PATH, encargada de definir las rutas hacia los binarios (comandos) del sistema operativo.

Bajo cron, las rutas hacia los binarios (comandos) incluidas en PATH no son las mismas que las de una sesión corriente, por lo que algunos de los comandos invocados desde el script no se ejecutarán. Digamos que el script no encontrará los comandos.

En una sesión como root en una terminal, podemos ver las rutas incluidas en la variable de entorno PATH, es decir, las rutas donde se encuentran los binarios del sistema, escribiendo:

HOST# echo $PATH /sbin:/usr/sbin:/usr/local/sbin:/root/bin:/usr/local/bin:/usr/bin:/bin

Para ver qué rutas contiene la variable PATH presente en el entorno generado por cron:

* * * * * env > /tmp/cronenv

Esto generará un archivo con las variables presentes en una sesión de cron.

Ahora, podemos emular el comportamiento de un script bajo las variables de entorno de cron:

env - $(cat /tmp/cronenv) /bin/sh

Esto hará que nuestra sesión actual tome las mismas variables de entorno presentes en cron cuando se ejcuta un script. Útil para testear y debugar shell scripts.

Alternativamente, podemos añadir la variable de entorno PATH al inicio del script en sí:

#!/bin/bash PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin ...

De la misma forma, se puede añadir la variable PATH al principio del archivo cron para que todos los archivos llamados desde cron cojan todas las rutas por defecto:

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin ...

Por último, y menos recomendable, podemos llamar a los binarios usando sus rutas absolutas.

Por ejemplo, para llamar al comando sendmail, deberemos llamarlo con la ruta absoluta del binario:

#!/bin/bash /sbin/sendmail ...
0

0 comentarios:

Publicar un comentario