La cron
utilidad de línea de comandos es un programador de tareas en sistemas operativos tipo Unix . Los usuarios que configuran y mantienen entornos de software utilizan cron para programar tareas [1] (comandos o scripts de shell ), también conocidos como trabajos cron , [2] [3] para que se ejecuten periódicamente en horas, fechas o intervalos fijos. [4] Por lo general, automatiza el mantenimiento o la administración del sistema, aunque su naturaleza de propósito general lo hace útil para cosas como descargar archivos de Internet y descargar correo electrónico a intervalos regulares. [5]
Cron es más adecuado para programar tareas repetitivas. La programación de tareas únicas se puede realizar mediante la utilidad asociada at .
El nombre de Cron proviene de Chronos , la palabra griega para tiempo. [6] [ se necesita una mejor fuente ]
Las acciones de cron se controlan mediante un archivo crontab (tabla cron), un archivo de configuración que especifica los comandos de shell que se ejecutarán periódicamente según un cronograma determinado. Los archivos crontab se almacenan en el mismo lugar donde se guardan las listas de trabajos y otras instrucciones para el demonio cron . Los usuarios pueden tener sus propios archivos crontab individuales y, a menudo, hay un archivo crontab para todo el sistema (normalmente en /etc
o en un subdirectorio de, /etc
por ejemplo /etc/cron.d
) que sólo los administradores del sistema pueden editar. [nota 1]
Cada línea de un archivo crontab representa un trabajo y tiene este aspecto:
# * * * * * <comando a ejecutar> # | | | | | # | | | | día de la semana (0–6) (de domingo a sábado; # | | | mes (1–12) 7 también es domingo en algunos sistemas) # | | día del mes (1–31) # | hora (0–23) # minuto (0–59)
La sintaxis de cada línea espera una expresión cron compuesta de cinco campos que representan el tiempo para ejecutar el comando, seguido de un comando de shell para ejecutar.
Aunque normalmente el trabajo se ejecuta cuando todos los campos de especificación de fecha y hora coinciden con la fecha y hora actuales, hay una excepción: si tanto el "día del mes" (campo 3) como el "día de la semana" (campo 5) están restringidos (no contienen "*"), entonces uno o ambos deben coincidir con el día actual. [7]
Por ejemplo, lo siguiente borra el registro de errores de Apache un minuto después de la medianoche (00:01) todos los días, asumiendo que el shell predeterminado para el usuario cron es compatible con Bourne Shell :
1 0 * * * printf "" > /var/log/apache/error_log
Este ejemplo ejecuta un programa de shell llamado export_dump.sh a las 23:45 (11:45 p.m.) todos los sábados.
45 23 * * 6 /home/oracle/scripts/export_dump.sh
Nota: En algunos sistemas también es posible especificar */n
que se ejecute cada n -ésimo intervalo de tiempo. Además, se pueden especificar varios intervalos de tiempo específicos con comas (por ejemplo, 1,2,3
). La línea siguiente generaría "hola mundo" en la línea de comandos cada 5 minutos de cada primera, segunda y tercera hora (es decir, 01:00, 01:05, 01:10, hasta 03:55).
*/5 1 ,2,3 * * * echo hola mundo
El archivo de configuración de un usuario se puede editar mediante una llamada, crontab -e
independientemente de dónde la implementación real almacene este archivo.
Algunas cron
implementaciones, como la popular cuarta edición de BSD escrita por Paul Vixie e incluida en muchas distribuciones de Linux, agregan un sexto campo: un nombre de usuario de cuenta que ejecuta el trabajo especificado (sujeto a la existencia y los permisos del usuario). Esto solo se permite en las crontabs del sistema, no en otras, que se asignan a un solo usuario para configurar. El sexto campo se usa a veces como alternativa para el año en lugar de un nombre de usuario de cuenta; el demonio nncron para Windows lo hace.
La implementación de cron de Amazon EventBridge no utiliza el día de la semana basado en 0, sino que es 1-7 de domingo a sábado (en lugar de 0-6), y también admite funciones de expresión adicionales como el primer día de la semana y el último día del mes. [8]
Algunas implementaciones de cron [9] admiten las siguientes macros no estándar:
@reboot
configura un trabajo para que se ejecute una vez cuando se inicia el demonio. Dado que cron normalmente no se reinicia nunca, esto generalmente corresponde al inicio de la máquina. Este comportamiento se aplica en algunas variantes de cron, como la que se proporciona en Debian [10] , de modo que simplemente reiniciar el demonio no vuelva a ejecutar @reboot
los trabajos.
@reboot
Puede ser útil si es necesario iniciar un servidor o demonio bajo un usuario en particular y el usuario no tiene acceso para configurar init para iniciar el programa.
Estos dos archivos juegan un papel importante:
Tenga en cuenta que si ninguno de estos archivos existe, entonces, dependiendo de los parámetros de configuración dependientes del sitio, solo el superusuario puede usar trabajos cron o todos los usuarios pueden usar trabajos cron.
La mayoría de las implementaciones de cron simplemente interpretan las entradas de crontab en la configuración de zona horaria del sistema bajo la que se ejecuta el demonio de cron. Esto puede ser una fuente de disputa si una gran máquina multiusuario tiene usuarios en varias zonas horarias, especialmente si la zona horaria predeterminada del sistema incluye el potencialmente confuso DST . Por lo tanto, una implementación de cron puede, como caso especial, reconocer líneas de la forma "CRON_TZ=<zona horaria>" en crontabs de usuario, interpretando las entradas de crontab posteriores en relación con esa zona horaria. [11]
El cron en la versión 7 de Unix era un servicio del sistema (más tarde llamado daemon ) que se invocaba /etc/rc
cuando el sistema operativo entraba en modo multiusuario. [12] Su algoritmo era sencillo:
/usr/lib/crontab
[13]Esta versión de cron era básica y robusta, pero también consumía recursos, ya sea que encontrara trabajo que hacer o no. En un experimento realizado en la Universidad de Purdue a fines de la década de 1970 para extender el servicio de cron a los 100 usuarios en un VAX de tiempo compartido , se descubrió que representaba una carga excesiva para el sistema.
La siguiente versión de cron, con el lanzamiento de Unix System V , se creó para extender las capacidades de cron a todos los usuarios de un sistema Unix, no solo al superusuario. Aunque esto puede parecer trivial hoy en día, ya que la mayoría de los sistemas Unix y similares tienen procesadores potentes y una pequeña cantidad de usuarios, en ese momento requería un nuevo enfoque en un sistema de un MIPS que tenía aproximadamente 100 cuentas de usuario.
En la edición de agosto de 1977 de Communications of the ACM , WR Franta y Kurt Maly publicaron un artículo titulado "Una estructura de datos eficiente para el conjunto de eventos de simulación", que describe una estructura de datos de cola de eventos para sistemas de simulación discretos impulsados por eventos que demostró "un rendimiento superior al de los algoritmos de lista enlazada simple comúnmente utilizados", buen comportamiento dadas distribuciones de tiempo no uniformes y la peor complejidad de los casos , siendo "n" el número de eventos en la cola.
Un estudiante de posgrado de Purdue, Robert Brown, al revisar este artículo, reconoció el paralelismo entre cron y los simuladores de eventos discretos , y creó una implementación del administrador de listas de eventos (ELM) de Franta-Maly para experimentación. Los simuladores de eventos discretos se ejecutan en tiempo virtual , extrayendo eventos de la cola de eventos lo más rápido posible y avanzando su noción de "ahora" hasta el momento programado del próximo evento. La ejecución del simulador de eventos en "tiempo real" en lugar de tiempo virtual creó una versión de cron que pasaba la mayor parte del tiempo durmiendo, esperando el momento programado para ejecutar la tarea al principio de la lista de eventos.
El año escolar siguiente, nuevos estudiantes ingresaron al programa de posgrado de Purdue, entre ellos Keith Williamson, quien se unió al personal de sistemas del departamento de Ciencias de la Computación. Como "tarea de calentamiento", Brown le pidió que desarrollara el prototipo de cron para convertirlo en un servicio de producción, y este cron multiusuario comenzó a usarse en Purdue a fines de 1979. Esta versión de cron reemplazó por completo al /etc/cron
que se usaba en el VAX 11/780 del departamento de Ciencias de la Computación que funcionaba con 32/V.
El algoritmo utilizado por este cron es el siguiente:
.crontab
en los directorios de inicio de todos los titulares de cuentas.Además, el demonio responde a las señales SIGHUP para volver a escanear los archivos crontab modificados y programa "eventos de activación" especiales a la hora y a la media hora para buscar archivos crontab modificados. Se omiten muchos detalles aquí sobre las imprecisiones del seguimiento de la hora del día de la computadora, la programación de alarmas de Unix, los cambios explícitos de la hora del día y la gestión de procesos, todos los cuales representan la mayoría de las líneas de código en este cron. Este cron también capturó la salida de stdout y stderr y envió por correo electrónico cualquier salida al propietario del crontab.
Los recursos consumidos por este cron escalan solo con la cantidad de trabajo que se le asigna y no aumentan inherentemente con el tiempo, con la excepción de la verificación periódica de cambios.
Williamson completó sus estudios y dejó la Universidad con una Maestría en Ciencias de la Computación y se unió a AT&T Bell Labs en Murray Hill, Nueva Jersey, y se llevó este cron con él. En Bell Labs, él y otros incorporaron el comando Unixat
a cron, movieron los archivos crontab fuera de los directorios personales de los usuarios (que no eran específicos del host) y a un directorio de spool específico del host común, y por necesidad agregaron el crontab
comando para permitir a los usuarios copiar sus crontabs a ese directorio de spool.
Esta versión de cron apareció más tarde, sin apenas modificaciones, en Unix System V y en BSD y sus derivados, Solaris de Sun Microsystems , IRIX de Silicon Graphics , HP-UX de Hewlett-Packard y AIX de IBM . Técnicamente, la licencia original de estas implementaciones debería pertenecer a la Purdue Research Foundation, que financió el trabajo, pero esto ocurrió en una época en la que se prestaba poca atención a estos asuntos.
Con la llegada del Proyecto GNU y Linux , aparecieron nuevos crons. El más común de ellos es el cron Vixie, codificado originalmente por Paul Vixie en 1987. La versión 3 de Vixie cron se lanzó a fines de 1993. La versión 4.1 se renombró como ISC Cron y se lanzó en enero de 2004. La versión 3, con algunas correcciones de errores menores, se usa en la mayoría de las distribuciones de Linux y BSD.
En 2007, Red Hat bifurcó vixie-cron 4.1 en el proyecto cronie e incluyó anacron 2.3 en 2009 [ cita requerida ] . Sin embargo, Anacron no es un programa cron independiente; otro trabajo cron debe llamarlo.
El dcron de DragonFly fue creado por su fundador Matt Dillon , y su mantenimiento fue asumido por Jim Pryor en 2010. [14]
En 2003, Dale Mellor introdujo mcron, [15] una variante de cron escrita en Guile que proporciona compatibilidad cruzada con Vixie cron y al mismo tiempo proporciona mayor flexibilidad ya que permite utilizar código de esquema arbitrario en los cálculos de programación y definiciones de trabajos. Dado que tanto el demonio mcron como los archivos crontab suelen estar escritos en scheme (aunque mcron también acepta crontabs tradicionales de Vixie), el estado acumulativo de la cola de trabajos de un usuario está disponible para su código de trabajo, que puede programarse para ejecutarse si y solo si los resultados de otros trabajos cumplen ciertos criterios. Mcron se implementa de forma predeterminada en el administrador de paquetes Guix , que incluye disposiciones ( servicios ) para que el administrador de paquetes emita crontabs mcron de forma monádica mientras garantiza que los paquetes necesarios para la ejecución del trabajo estén instalados y que los crontabs correspondientes se refieran a ellos correctamente. [16]
Una solución webcron programa tareas de anillo para que se ejecuten periódicamente dondequiera que las implementaciones de cron no estén disponibles en un entorno de alojamiento web .
Una expresión cron es una cadena compuesta por cinco o seis campos separados por espacios en blanco [17] que representa un conjunto de tiempos, normalmente como un cronograma para ejecutar alguna rutina.
Los comentarios comienzan con un símbolo de comentario # y deben estar en una línea aparte.
Las abreviaturas de mes y día de la semana no distinguen entre mayúsculas y minúsculas.
En el caso particular del archivo crontab del sistema (/etc/crontab), se inserta un campo de usuario antes del comando . Generalmente, se configura como 'root'.
En algunos usos del formato cron también hay un campo de segundos al comienzo del patrón. En ese caso, la expresión cron es una cadena que comprende 6 o 7 campos. [18]
*
),
)-
)%
)Los siguientes son caracteres no estándar y solo existen en algunas implementaciones de cron, como el programador Java Quartz .
L
W
#
)?
)? ? * * * *
25 8 * * * *
/
)Tenga en cuenta que las frecuencias en general no se pueden expresar; solo los valores de paso que dividen uniformemente su rango expresan frecuencias precisas (para minutos y segundos, es /2, /3, /4, /5, /6, /10, /12, /15, /20 y /30 porque 60 es divisible uniformemente por esos números; para horas, es /2, /3, /4, /6, /8 y /12 ); todos los demás "pasos" posibles y todos los demás campos producen períodos "cortos" inconsistentes al final de la unidad de tiempo antes de que se "reinicie" al siguiente minuto, segundo o día; por ejemplo, ingresar */5 para el campo de día a veces se ejecuta después de 1, 2 o 3 días, dependiendo del mes y el año bisiesto; esto se debe a que cron no tiene estado (no recuerda la hora de la última ejecución ni cuenta la diferencia entre esta y ahora, requerida para un conteo de frecuencia preciso; en cambio, cron es un mero comparador de patrones).
Algunas bibliotecas específicas de lenguaje que ofrecen la capacidad de programación crontab no requieren rangos "estrictos" 15-59/XX a la izquierda de la barra cuando se utilizan rangos. [22] En estos casos, 15/XX es lo mismo que una programación vixie-cron de 15-59/10 en la sección de minutos. De manera similar, puede eliminar el -23 adicional de 0-23/XX , -31 de 1-31/XX y -12 de 1-12/XX para horas, días y meses; respectivamente.
H
20 * * * *
", que significa 20 minutos después de la hora cada hora, " H * * * *
" indica que la tarea se realiza cada hora a una hora no especificada pero invariable para cada tarea. Esto permite distribuir las tareas a lo largo del tiempo, en lugar de que todas comiencen al mismo tiempo y compitan por los recursos. [23]