¿Qué es cron?
Cron es el programador de tareas de Linux y de macOS: ejecuta un comando o un script cuando toca, sin que nadie tenga que estar delante. Se usa para hacer copias de seguridad por la noche, enviar boletines, vaciar cachés o lanzar los procesos de una web cada pocos minutos. Cada tarea es una línea del crontab con una expresión que dice cuándo se ejecuta, seguida del comando.
Los cinco campos
┌────────────── minuto (0-59) │ ┌─────────── hora (0-23) │ │ ┌───────── día del mes (1-31) │ │ │ ┌─────── mes (1-12 o JAN-DEC) │ │ │ │ ┌───── día de la semana (0-7 o SUN-SAT: 0 y 7 son domingo) │ │ │ │ │ 30 2 * * 1-5 /ruta/al/script.sh
Se leen de izquierda a derecha: la línea del ejemplo se ejecuta a las 2:30 de la madrugada, de lunes a viernes. Los meses y los días de la semana también se pueden escribir con sus tres primeras letras en inglés (JAN, MON…).
Los caracteres especiales
| Escribe | Significa | Ejemplo |
|---|---|---|
* | Todos los valores | * en la hora → cada hora |
, | Una lista de valores | 8,14,20 en la hora → a las 8, a las 14 y a las 20 |
- | Un rango | 1-5 en el día de la semana → de lunes a viernes |
/ | Un paso: de tanto en tanto | */15 en el minuto → cada 15 minutos; 0-30/10 → en los minutos 0, 10, 20 y 30 |
Expresiones cron habituales
Las mismas que puedes cargar con un clic en los ejemplos de arriba.
| Expresión | Se ejecuta |
|---|---|
*/5 * * * * | Cada 5 minutos |
0 * * * * | Cada hora en punto |
0 3 * * * | A las 03:00, todos los días |
30 2 * * 1-5 | A las 02:30, de lunes a viernes |
*/15 9-18 * * 1-5 | Cada 15 minutos, de 09:00 a 18:45, de lunes a viernes |
0 0 * * 0 | A las 00:00, los domingos |
0 6 1 * * | A las 06:00, el día 1 de cada mes |
0 0 1 1 * | A las 00:00, el 1 de enero |
Los atajos
Casi todas las versiones de cron admiten estos atajos en lugar de los cinco campos: @hourly (cada hora, 0 * * * *), @daily o @midnight (cada día a medianoche, 0 0 * * *), @weekly (los domingos a medianoche, 0 0 * * 0), @monthly (el día 1 de cada mes, 0 0 1 * *) y @yearly o @annually (el 1 de enero, 0 0 1 1 *). Además, @reboot ejecuta la tarea una vez cada vez que arranca el servidor.
La trampa del día del mes y el día de la semana
Si pones a la vez un día del mes y un día de la semana, cron no busca los días que cumplan las dos cosas, sino los que cumplen cualquiera de ellas. 0 0 13 * 5 no se ejecuta los viernes 13, sino todos los días 13 y, además, todos los viernes. Para lo primero, deja solo uno de los dos y comprueba el otro en el propio comando.
El último día del mes
El cron de Linux no tiene una forma de decir «el último día del mes», y 0 0 31 * * se salta los meses de 30 días y febrero. La solución habitual es ejecutarlo del 28 al 31 y que el comando compruebe si mañana es día 1:
0 23 28-31 * * [ "$(date -d tomorrow +\%d)" = "01" ] && /ruta/al/script.sh
El % va escapado (\%) porque en el crontab es un carácter especial: marca un salto de línea. Es un error muy común al copiar comandos con fechas.
La zona horaria y el cambio de hora
Cron usa la hora del servidor, que no tiene por qué ser la tuya: muchos servidores, y siempre GitHub Actions, trabajan en UTC, que en España es una hora menos en invierno y dos menos en verano. Con el botón UTC de arriba ves cuándo se ejecutará en ellos.
Si el servidor tiene la hora de España, cuidado con las tareas entre las 2:00 y las 2:59: el último domingo de marzo esa hora no existe y el último domingo de octubre pasa dos veces. Cada sistema lo resuelve a su manera, así que para una tarea importante es mejor elegir otra hora.
Cron en Plesk, cPanel y el terminal
- En Plesk, en las tareas programadas del dominio, puedes elegir que la frecuencia se escriba con el formato de cron y pegar ahí la expresión.
- En cPanel, en «Trabajos de cron» hay un campo para cada uno de los cinco valores, o una lista de ajustes comunes.
- En un servidor por SSH,
crontab -eabre las tareas de tu usuario ycrontab -llas muestra. Usa rutas completas (/usr/bin/php, nophp), porque cron arranca con muy pocas variables de entorno, y guarda la salida en un archivo para ver los errores:>> /var/log/tarea.log 2>&1.
Cron sin segundos: Quartz y Spring
El cron de Linux no baja de un minuto. Las expresiones de seis o siete campos que se ven por internet, como 0 30 2 * * ?, son de Quartz y Spring (Java): llevan los segundos delante, a veces el año al final, y caracteres como ?, L o # que el cron de Linux no entiende. Para pasarlas a cron, quita los segundos y el año y cambia el ? por *.