En mi caso tengo un script y cuando lo ejecuto manualmente funciona a la perfección. El problema es que cuando quiero programar su ejecución mediante cron el script no se ejecuta y/o no hace lo que hay que hacer. En el caso que se encuentren en un caso similar al mío les recomiendo que hagan lo siguiente.

¿POR QUÉ NO ES SE EJECUTA CORRECTAMENTE UN SCRIPT MEDIANTE CRON?

El primero motivo podría ser que la sintaxis usada no sea correcta, pero este caso es poco probable porque si la sintaxis fuera incorrecta la terminal arrojaría un error y lo veríamos claramente.

El segunda opción es que nuestro script haga uso de un fichero binario cuyo PATH no está correctamente definido en Cron.

¿Pero que es el PATH o la ruta en Linux?

El PATH o la ruta es una variable de entorno cuya función es definir la ubicación de los distintos binarios de nuestro sistema operativo. Tenéis que tener presente que cada vez que ejecutamos un comando, la shell de Linux buscará en todos y cada uno de los directorios definidos en el PATH para encontrar el binario y de esta forma poder ejecutar el comando.

¿Cuál es el PATH de mi usuario?

Cada uno de los procesos de ejecución o cada una de la sesiones de usuario pueden tener un PATH diferente. Si por ejemplo queremos ver el PATH de nuestro usuario tan solo tenemos que abrir una terminal y ejecutar el siguiente comando:

joan@ubuntu-20-04:~$ echo $PATH
/home/joan/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games

Por lo tanto después de ejecutar el comando vemos que el usuario joan tiene definido el siguiente PATH:

/home/joan/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games

En este caso el usuario joan podrá ejecutar cualquier binario que esté dentro de las rutas especificadas dentro de la variable de entorno PATH.

¿Cuál es el PATH establecido en las tareas que ejecuta CRON?

Para averiguar el PATH definido en cron tan solo tenemos que realizar lo siguiente.

Inicialmente ejecutamos el siguiente comando en la terminal:

joan@ubuntu-20-04:~$ crontab -e

A continuación cuando se abra el editor de textos para editar el contenido de crontab añadimos la siguiente línea y guardamos los cambios.

* * * * * env > /tmp/cronenv

Una vez guardados los cambios tenemos que esperar 1 minuto. Después de esperar un minuto consultaremos el contenido del fichero /tmp/cronenv para ver la totalidad de variables de entorno definidas en CRON. En mi caso las variables de entorno de cron son las siguientes:

joan@ubuntu-20-04:~$ cat /tmp/cronenv
HOME=/home/joan
LOGNAME=joan
PATH=/usr/bin:/bin
LANG=es_ES.UTF-8
SHELL=/bin/sh
PWD=/home/joan

Si analizamos el contenido de la variable de entorno PATH vemos que únicamente contiene las rutas /usr/bin y /bin. Por lo tanto cron solo podrá ejecutar scripts que contengan comandos cuyos ficheros binarios estén ubicados en /usr/bin o /bin. Si os fijáis el PATH de la sesión de usuario de joan es totalmente diferente al PATH del cron y posiblemente este sea el motivo de nuestros problemas.

Simular la ejecución de un script con las variables de entorno definidas en CRON

Para confirmar que el problema es el que acabo de citar ejecutaremos el script que nos da los problemas con las mismas variables de entorno definidas en cron. Para ello ejecutaremos el comando env - $(cat /tmp/cronenv) seguido del comando necesario para ejecutar el script que da problemas. Por lo tanto en mi caso el comando que tengo que ejecutar es el siguiente:

joan@ubuntu-20-04:~$ env - $(cat /tmp/cronenv) bash /home/joan/scripts/audiobookyoutube/audioyoutube.sh

Después de ejecutar el script veo que en la salida estándar de la terminal se produce el siguiente error.

/home/joan/scripts/audiobookyoutube/audioyoutube.sh: línea 66: yt-dlp: orden no encontrada

Por lo tanto el problema es que yt-dlp no se puede ejecutar. El motivo por el cual no se ejecuta es simple:

  • En mi caso el binario de yt-dlp se halla en la ubicación /home/joan/.local/bin. Como hemos visto anteriormente está ruta no está presente en el PATH del cron. Por lo tanto es normal que el script falle en su ejecución.

COMO SOLUCIONAR EL PROBLEMA DEL PATH EN CRON Y DE ESTA FORMA EJECUTAR EL SCRIPT DE FORMA SATISFACTORIA

Para solucionar el problema mostrado en esté artículo tan solo tenemos que añadir la ruta /home/joan/.local/bin en el PATH de cron. Para ello tenemos varias soluciones.

Definir el PATH de cron en el fichero crontab

La primera de las soluciones es añadir el PATH de cron dentro del fichero crontab del usuario que ejecutará el script. Para ello tan solo tenemos que loguear con el usuario apropiado, abrir una terminal y ejecutar el siguiente comando:

joan@ubuntu-20-04:~$ crontab -e

Una vez se abra el fichero crontab introduciremos una línea del siguiente tipo justo al inicio del fichero para definir el PATH:

PATH=RUTA_BINARIOS1:RUTA_BINARIOS2:RUTA_BINARIOS3

Por lo tanto en mi caso añadiré la siguiente línea al inicio de mi fichero crontab:

PATH=/usr/bin:/bin:/home/joan/.local/bin

Finalmente guardaremos los cambios y cerraremos el fichero. Ahora cuando se ejecute un script mediante cron se considerarán todos los binarios ubicados en la ruta /home/joan/.local/bin. Por lo tanto se podrá ejecutar yt-dlp y de este modo se debería ejecutar el script sin ningún tipo de problema. Por lo tanto hemos solucionado el problema que un script no se ejecuta en cron.

Definir el PATH de ejecución dentro del script

Otra opción alternativa a la que acabamos de ver es definir el PATH dentro del script que queremos ejecutar. En mi caso el script que me da problemas es el /home/joan/scripts/audiobookyoutube/audioyoutube.sh. Por lo tanto lo único que tengo que realizar es abrirlo mediante el siguiente comando:

joan@ubuntu-20-04:~$ nano /home/joan/scripts/audiobookyoutube/audioyoutube.sh

Una vez abierto defino el PATH justo después del Shebang. En mi caso lo he realizado del siguiente modo:

#!/bin/bash
PATH=/usr/bin:/bin:/home/joan/.local/bin

Una vez guardados las modificaciones realizadas en el script cron será capaz de ejecutar el script sin ningún tipo de problema.

Únete a la conversación

4 comentarios

  1. También es importante tener en cuenta qué Shell estás usando (en cron por defecto es SH, sin embargo, los entornos de escritorio suelen venir con BASH), y que en un script de cron el símbolo % tiene que se escapado. Por ejemplo, `date +%Y-%m-%d` no funcionará, hay que ponerlo así: `date +\%Y-\%m-\%d`

  2. Realmente funciona. Tenía el mismo problema y ya no sabía qué método utilizar, había probado con todo. Hasta que encontré este artículo con la solución magistral al problema. Gracias por compartir

Dejar un comentario

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

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.