CRON es el «programador de tareas» de Linux, que nos permite ejecutar tareas de forma automática y periódica. A veces, un script que funciona bien en el shell del usuario, no se ejecuta en CRON. Explicamos cómo averiguar el motivo por el que no se ejecuta una tarea programada CRON en Linux. Cómo ejecutar un script simulando el entorno del cron y cómo solucionar el error de ejecución en cron.

Síntomas, la tarea CRON no se ejecuta

En un entorno de producción, cuando tenemos un script SH que se ejecuta correctamente desde la línea de comandos, por ejemplo el que tenemos en:

Accediendo a dicha carpeta:

Y ejecutando el script switch_oficina_1.sh:

El script anterior, en la línea de comandos, con el usuario root, se ejecutará correctamente:

Síntomas, la tarea CRON no se ejecuta

Pero al programar en el CRON con:

Y añadiendo la línea:

0 21 * * sun /home/cisco/script/switch_oficina_1.sh

Vemos que, el sábado a las 9 de la noche (según la programación), NO se ejecuta correctamente el script.

Motivos por los que no se ha ejecutado una tarea CRON en Linux

Los motivos por los que un script no se ha ejecutado de forma automática con CRON pueden ser muchos. Pero si el script funciona correctamente en la línea de comandos, se reducen a unos pocos.

Uno de ellos es por permisos. Cuando definimos una tarea cron en un usuario concreto de Linux, debemos asegurarnos de que dicho usuario tiene permisos suficientes para ejecutar el script.

Por otro lado, revisaremos que hemos añadido correctamente la ruta del script a ejecutar en la línea del cron:

0 21 * * sun /home/cisco/script/switch_oficina_1.sh

Debe existir el fichero en la ruta indicada y el usuario debe tener permisos para ejecutarlo.

Además, dicho fichero de script debe tener el permiso de ejecución:

A veces no hemos indicado correctamente la periodicidad de ejecución. En CRON hay que tener en cuenta lo siguiente. Se compone, en resumidas cuentas, de tantas líneas como tareas quieran ejecutarse. Cada línea tendrá la siguiente estructura:

* * * * * /ruta_script/script

Donde:

  • El primer asterisco sirve para indicar el minuto: 0..59.
  • El segundo asterisco sirve para indicar la hora: 0..23.
  • El tercer asterisco sirve para indicar el día: 1..31.
  • El cuarto asterisco sirve para indicar el mes: 1..12
  • El quinto asterisco sirve para indicar el día de la semana: 0..6 (0 es domingo).

Por lo tanto nos aseguraremos de tener correctamente configurada la línea. Por ejemplo, para que una tarea se ejecute todos los sábados a las 21 horas, tendremos la línea:

0 21 * * sun /home/cisco/script/switch_oficina_1.sh

(el día de la semana se puede poner en número o con letras «sun» = 0)

Averiguar el motivo por el que una tarea programada cron no se ejecuta en Linux

Revisando el fichero de log de cron

En primer lugar, revisaremos el fichero de log de cron, que es donde Linux guarda el resultado de la ejecución de las tareas automáticas. Suele guardarse en el fichero syslog, de eventos del sistema. Por ello, ejecutando el siguiente comando, filtraremos todos los eventos generados por cron en /var/log/syslog:

Con esto, a veces, podremos averiguar el motivo por el que no se ejecuta la tarea programada cron. Mostrará líneas como esta:

Jun 26 23:17:01 srvftp CRON[4914]: (root) CMD ( cd / && run-parts –report /e tc/cron.hourly)
Jun 27 00:17:01 srvftp CRON[5037]: (root) CMD ( cd / && run-parts –report /e tc/cron.hourly)

Si con esto no somos capaces de obtener el motivo del error de la ejecución de la tarea programada, realizaremos los siguientes pasos para simular el entorno de ejecución real de una tarea programada cron.

Enviando resultado del cron a un fichero

También podremos enviar el resultado de la ejecución del script del cron a un fichero de log. De esta forma, podremos saber si se ha ejecutado y el resultado de la ejecución. Para ello, en la tarea programada crontab, añadiremos al final:

0 21 * * sun /home/cisco/script/switch_oficina_1.sh >> /var/log/cron_root 2>&1

En este caso, cuando se ejecute la tarea, se creará un fichero en /var/log llamado «cron_root». Dicho fichero contendrá el resultado de la ejecución del script.

En caso de no generarse en fichero de salida, puede deberse a varios motivos:

  • No tener permisos suficientes para crear ficheros en la carpeta indicada por el usuario del entorno crontab que usemos.
  • No se ha ejecutado la tarea programada, normalmente por una mala configuración en sus parámetros de periodicidad.

Simulando la ejecución del script con el entorno del cron

Cuando ejecutamos un script en cron, es muy importante saber que se ejecuta con el entorno (environment) del usuario en el que se definió dicha tarea. En nuestro escenario hemos creado la tarea programada cron en el usuario root. Lo que haremos para simular este entorno es, en primer lugar, crear una tarea programada cron en este usuario, con:

Donde indicaremos que se ejecute cada minuto (dejando los cinco asteriscos) y en el script de ejecución indicaremos:

env > /tmp/cronenv_root

Quedando la línea:

* * * * env > /tmp/cronenv_root

Guardando los cambios en el cron y transcurrido un minuto, nos habrá generado un fichero en /tmp llamado «cronenv_root». Podremos detener la tarea volviendo a editar el cron y comentándola añadiendo almohadilla delante (#) o bien eliminándola, ya no la necesitamos.

Como decimos, tendremos el fichero /tmp/cronenv_root, que tendrá el siguiente contenido:

HOME=/root
LOGNAME=root
PATH=/usr/bin:/bin
LANG=es_ES.UTF-8
SHELL=/bin/sh
PWD=/root

Simulando la ejecución del script con el entorno del cron

En este caso, el usuario root podrá ejecutar aplicaciones (sin introducir el path completo) que estén en /root, /usr/bin, /bin/sh. Si en el script hay alguna aplicación/script que esté fuera de estas carpetas, deberemos indicar el path completo para que root las encuentre.

Ahora realizaremos una prueba de ejecución del script del cron pero en el shell del usuario root, simulando el entorno que usará en el cron, con el comando:

Donde:

  • /tmp/cronenv_root: ruta y nombre del fichero generado desde la tarea de cron con el entorno de ejecución (environment).
  • /home/cisco/script/switch_oficina_1.sh: ruta y nombre del script SH que se ejecutará en el cron y que queremos comprobar simulando el mismo entorno que en su ejecución desde cron.
Simulando la ejecución del script con el entorno del cron

Vemos que en este caso se produce un error al intentar ejecutar el script del cron desde su entorno de ejecución:

/home/cisco/script/switch_oficina_1.sh: 3: ./backup_cisco.sh: not found

Indicando que hay otro script que no encuentra: ./backup_cisco.sh

Si revisamos el script ejecutado por cron:

Vemos que intenta ejecutar otro script, backup_cisco.sh, en el directorio actual (punto delante), y el directorio actual de ejecución de cron no es el del script. Por lo tanto no lo encuentra.

Solución al error en la ejecución de script en tarea programada cron

Para solucionar este error, dado que se trata de un problema de rutas (path), estableceremos la ruta del script a ejecutar, cambiando el anterior por:

Guardando los cambios y volviendo a ejecutar el script simulando el entorno de ejecución del cron, veremos que ahora sí funciona:

Solución al error en la ejecución de script en tarea programada cron

Por lo tanto, la tarea programada cron también funcionará a partir de ahora.

Como hemos comprobado, muchos de los errores de ejecución de tareas en cron son debidos a las rutas (path), que consideramos establecidas en el usuario al realizar las pruebas, pero que no siempre son las mismas en el entorno de ejecución de cron.