Programar tareas con Cron Jobs

Trabajaremos con el cron para utilizar la programación de tareas y ejecutar en el servidor un proceso en una hora determinada en un rango de tiempo. Se usan más comúnmente para la automatización de mantenimiento o administración del sistema. Sin embargo, también son relevantes para el desarrollo de aplicaciones web. Hay muchas situaciones en las que una aplicación web puede necesitar ciertas tareas para ejecutarse periódicamente. Hoy vamos a explorar los fundamentos de Cron Jobs.

Definiciones

Primero vamos a familiarizarnos con los términos relacionados con este tema.
"Cron" es un planificador de tareas basadas en el tiempo en los sistemas operativos de tipo Unix (Linux, FreeBSD, Mac OS, etc ..). Y estos trabajos o tareas se denominan "Cron Jobs".
Hay un "daemon" cron que se ejecuta en estos sistemas. Un demonio es un programa que se ejecuta en segundo plano todo el tiempo, por lo general iniciada por el sistema.Este demonio cron es responsable del lanzamiento de estos trabajos cron en la fecha prevista.
El programa consiste en un archivo de configuración llamado "crontab". Ahí es donde se listan todas las tareas y sus cronómetros.

¿Por qué utilizar Cron Jobs?

Los administradores del servidor han estado utilizando cron puestos de trabajo durante mucho tiempo. Pero dado que el público objetivo de este artículo es a los desarrolladores web, echemos un vistazo a un par de casos de uso de trabajos de cron que son relevantes en esta área:
  • Si usted tiene un sitio de pertenencia, donde las cuentas tienen fecha de vencimiento, puede programar cron puestos de trabajo, para desactivar o eliminar regularmente las cuentas que están más allá de sus fechas de vencimiento.
  • Usted puede enviar mensajes de correo electrónico del boletín de noticias diarias.
  • Si tiene tablas de resumen (o vistas materializadas) en su base de datos, pueden ser actualizada periódicamente con un trabajo cron. Por ejemplo, puede almacenar todas las páginas web hit en una tabla, sino otra tabla resumen puede contener resúmenes diarios de tráfico.
  • Usted puede vencer y borrar archivos de datos almacenados en caché en un intervalo determinado.
  • Usted puede auto-revisar su contenido del sitio web de enlaces rotos y tienen un informe por correo electrónico a ti mismo con regularidad.
  • Usted puede programar tareas de larga duración para ejecutarse desde un script de línea de comandos, en lugar de ejecutarlo desde un script web. Al igual que la codificación de vídeos, o el envío de correos electrónicos masivos.
  • Puedes incluso realizar algo tan simple como ir a buscar a tus Tweets más recientes, para ser almacenado en caché en un archivo de texto.

Sintaxis

Aquí es un simple trabajo de cron:
1
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">10 * * * * /usr/bin/php /www/virtual/username/cron.php > /dev/null 2>&1</span> 10 **** / usr / bin / php / www / virtual / nombre de usuario / cron.php> / dev / null 2> & 1</span>
Hay dos partes principales:
  1. La primera parte es "10 ****". Aquí es donde programamos el temporizador.
  2. El resto de la línea es el comando, ya que se extendería desde la línea de comandos.
El propio comando en este ejemplo tiene tres partes:
  1. "/ Usr / bin / php". Scripts PHP por lo general no son ejecutables por sí mismos.Por lo tanto tenemos que pasarla por el intérprete PHP.
  2. "/ Www / virtual / nombre de usuario / cron.php". Esto es sólo la ruta de acceso al script.
  3. "> / Dev / null 2> & 1". Esta parte está manejando la salida del script. Más sobre esto más adelante.

Timing Sintaxis

Esta es la primera parte de la cadena de trabajo de cron, como se mencionó anteriormente. Determina con qué frecuencia y cuando el trabajo de cron se va a ejecutar.
Se compone de cinco partes:
  1. minuto
  2. hora
  3. día del mes
  4. mes
  5. días de la semana
Aquí está un ejemplo:

Asterisco

Muy a menudo, usted verá un asterisco (*) en lugar de un número. Esto representa todos los números posibles para esa posición. Por ejemplo, asterisco en la posición de minutos podría hacer que se ejecute cada minuto.
Tenemos que mirar a algunos ejemplos para entender completamente esta sintaxis.

Ejemplos:

Este trabajo cron se ejecutará cada minuto, todo el tiempo:
1
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">* * * * * [command]</span> ***** [Comando]</span>
Este trabajo cron se ejecutará en el minuto cero, cada hora (es decir, un trabajo de cron cada hora):
1
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">0 * * * * [command]</span> 0 **** [comando]</span>
Esta es también una tarea de cron cada hora, pero correr en el minuto 15 en lugar (es decir, doce y cuarto, 1:15, 2:15, etc):
1
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">15 * * * * [command]</span> 15 **** [comando]</span>
Esto ejecutará una vez al día, a las 2:30 am:
1
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">30 2 * * * [command]</span> 30 2 *** [comando]</span>
Esto ejecutará una vez al mes, en el segundo día de cada mes a la medianoche (es decir, 02 de enero 12:00 h, 02 de febrero 12:00a.m. etc):
1
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">0 0 2 * * [command]</span> 0 0 2 ** [comando]</span>
Esto ejecutará los lunes, cada hora (es decir, 24 veces en un día, pero sólo los lunes):
1
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">0 * * * 1 [command]</span> 0 *** 1 [comando]</span>
Puede utilizar varios números separados por comas. Esto ejecutará tres veces cada hora, al minuto 0, 10 y 20:
1
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">0,10,20 * * * * [command]</span> 0,10,20 **** [comando]</span>
También se utiliza el operador división. Esto ejecutará 12 veces por hora, es decir, cada 5 minutos:
1
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">*/5 * * * * [command]</span> * / 5 **** [comando]</span>
Dash se puede utilizar para especificar un rango. Esto ejecutará una vez cada hora 05 a.m.-10 a.m.:
1
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">0 5-10 * * * [command]</span> 0 5-10 *** [comando]</span>
También hay una palabra clave especial que permite ejecutar una tarea de cron cada vez que se reinicia el servidor:
1
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">@reboot [command]</span> @ Reboot [comando]</span>

Configuración y gestión de Cron Jobs

Hay algunas maneras diferentes para crear y gestionar sus trabajos de cron.

Paneles de control

Muchas empresas de alojamiento web ofrecen paneles de control para sus clientes. Si usted es uno de ellos, usted puede ser capaz de encontrar una sección en su panel de control para administrar los trabajos de cron.

Edición del Crontab

Al ejecutar este comando lanzará vi (editor de texto) y le permitirá editar el contenido del crontab:
1
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">crontab -e</span> crontab-e</span>
Por lo tanto, ayudaría a estar familiarizados con los comandos básicos de vi , ya que es muy diferente a cualquier otro editor de texto que puede ser que haya trabajado.
Si usted simplemente quiere ver el crontab existente sin modificarlo, puede ejecutar el siguiente comando:
1
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">crontab -l</span> crontab-l</span>
Para borrar el contenido del crontab:
1
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">crontab -r</span> crontab-r</span>

Carga de un archivo

Usted puede escribir todos los trabajos cron en un archivo y luego haga clic en el crontab:
1
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">crontab cron.txt</span> cron.txt crontab</span>
Tenga cuidado, porque esto va a sobreescribir todos los trabajos cron existentes con los archivos de este contenido, sin previo aviso.

Comentarios

Usted puede agregar comentarios seguidos por el carácter #.
1
2
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"># This cron job does something very important</span> # Este trabajo cron hace algo muy importante</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">10 * * * * /usr/bin/php /www/virtual/username/cron.php > /dev/null 2>&1</span> 10 **** / usr / bin / php / www / virtual / nombre de usuario / cron.php> / dev / null 2> & 1</span>

Configuración del E-mail

Como mencioné anteriormente, por defecto la salida de los crons son enviadas a través de correo electrónico, a menos que descartes ellos o redirigir a un archivo. El nos dejó MAILTO ajuste que establecer o cambiar el que dirección de correo electrónico para enviarlos a:
1
2
3
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">MAILTO="username@example.com"</span> MAILTO = "username@example.com"</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"># This cron job does something very important</span> # Este trabajo cron hace algo muy importante</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">10 * * * * /usr/bin/php /www/virtual/username/cron.php > /dev/null 2>&1</span> 10 **** / usr / bin / php / www / virtual / nombre de usuario / cron.php> / dev / null 2> & 1</span>

Utilizando el Analizador PHP

Scripts CGI son ejecutables por defecto, pero los scripts PHP no lo son. Tienen que pasar por el intérprete PHP. Es por eso que tenemos que poner la ruta de acceso al programa de análisis antes de que la ruta del script.
1
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">* * * * * /usr/bin/php [path to php script]</span> ***** / Usr / bin / php [camino al script php]</span>
A veces puede ser que sea en virtud de otro lugar como: "/ usr / local / bin / php". Para averiguarlo, puede intentar ejecutar esto en la línea de comandos:
1
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">which php</span> que php</span>

Manejo de la salida

Si no se controla la salida de la secuencia de comandos cron, se enviará como mensajes de correo electrónico a tu cuenta de usuario en el servidor.

El descarte de salida

Si pones "> / dev / null 2> & 1" al final del comando cron job (o cualquier comando), la salida será descartado.
El corchete de cierre (>) se utiliza para redirigir la salida. "/ Dev / null" es como un agujero negro para la salida. Cualquier cosa que va allí es ignorado por el sistema.
Esta parte "2> & 1" hace que la salida stderr (error) para ser redirigido a la salida STDOUT (normal). Así que también termina en el directorio "/ dev / null".

Enviar a un archivo

Para guardar la salida en un archivo cron, use el corchete de cierre (>) de nuevo:
1
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">10 * * * * /usr/bin/php /www/virtual/username/cron.php > /var/log/cron.log</span> 10 **** / usr / bin / php / www / virtual / nombre de usuario / cron.php> / var / log / cron.log</span>
Eso reescribir el archivo de salida en todo momento. Si usted desea añada la salida al final del archivo en lugar de una reescritura completa, utilice paréntesis de cierre doble (>>) en su lugar:
1
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">10 * * * * /usr/bin/php /www/virtual/username/cron.php >> /var/log/cron.log</span> 10 **** / usr / bin / php / www / virtual / nombre de usuario / cron.php >> / var / log / cron.log</span>

Scripts ejecutables

Normalmente tiene que especificar el intérprete al comienzo de la orden como lo hemos venido haciendo. Pero en realidad hay una manera de hacer que los scripts PHP ejecutable desde la línea de comandos como un script CGI.
Usted necesita es añadir la ruta de acceso al programa de análisis como la primera línea del script:
1
2
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">#!/usr/local/bin/php</span> #! / Usr / local / bin / php</span>
<!--?php echo "hello world\n"; // ... ?-->
Asimismo, asegúrese de establecer chmod adecuada (como 755) para que el archivo ejecutable.
Cuando usted tiene un script ejecutable, el trabajo cron puede ser más corto de esta manera:
1
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">10 * * * * /www/virtual/username/hello.php</span> 10 **** / www / virtual / nombre de usuario / hello.php</span>

Prevención Cron Job Collision

En algunos casos puede que tenga cron puestos de trabajo en ejecución frecuentes, y es posible que no quiere que chocan si se tarda más tiempo en ejecutarse que la frecuencia propia.
Por ejemplo, usted puede tener un trabajo de cron ejecuta cada minuto. Sin embargo, de vez en cuando se puede tardar más de un minuto para correr. Esto puede hacer que otra instancia de la misma secuencia de comandos cron para empezar a correr antes de la una acabados anteriores. Puede crear demasiados procesos ocupados de esta manera y, posiblemente, bloquear el servidor si siguen retrasando el uno al otro, y causar aún más los procesos que se creen con el tiempo ..
Este problema puede abordarse mediante el bloqueo de archivos, y más específicamente el tipo de bloqueos de archivos sin bloqueo (LOCK_NB). (Si usted no está familiarizado con el bloqueo de archivos, le sugiero que lea sobre ella en primer lugar.)
Puede agregar este código al script cron job:
01
02
03
04
05
06
07
08
09
10
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">$fp = fopen('/tmp/lock.txt', 'r+');</span> $ Fp = fopen ('/ tmp / lock.txt', 'r +');</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">if(!flock($fp, LOCK_EX | LOCK_NB)) {</span> if (flock ($ fp, LOCK_EX |! LOCK_NB)) {</span>
    <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">echo 'Unable to obtain lock';</span> echo 'No se puede obtener de bloqueo';</span>
    <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">exit(-1);</span> exit (1);</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">}</span> }</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">/* ... */</span> / * ... * /</span>
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">fclose($fp);</span> fclose ($ fp);</span>
Con bloqueos de archivos regulares del rebaño () llamada a la función sería bloquear la secuencia de comandos si hay un bloqueo existente. Y que lanzaría una vez que el bloqueo se ha ido. Sin embargo, con una cerradura de no bloqueo, tal como en el código anterior, la llamada de función no se detiene la secuencia de comandos, pero devuelve inmediatamente FALSE si hay un bloqueo existente. Así que en este caso, se puede salir inmediatamente del script cuando vemos que hay un bloqueo existente, lo que indica que otro trabajo de cron se está ejecutando actualmente.

Bloqueadores de Acceso Web a Cron Jobs

Cuando se escribe un trabajo cron en un lenguaje de scripting web como PHP, es posible que desee asegurarse de que nadie puede ejecutarlo con sólo cargarlo de su navegador. Una opción sencilla sería la de almacenar estos guión fuera de su carpeta web. Sin embargo, esto puede no ser práctico o preferible para algunos desarrolladores, si quieren mantener sus scripts de tarea cron derecho dentro de sus carpetas de la aplicación web.
Si pones todos los scripts de tarea cron en una carpeta, a bloquear el acceso al poner esta línea en un archivo htaccess.:
1
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">deny from all</span> deny from all</span>
O también se puede denegar el acceso a los scripts de forma individual al poner esta línea al principio:
1
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">if (isset($_SERVER['REMOTE_ADDR'])) die('Permission denied.');</span> if (isset ($ _SERVER ['REMOTE_ADDR'])) die ('Permiso denegado.');</span>
Esto se asegurará de que, cuando se accede a la secuencia de comandos desde la web, se abortará inmediatamente.

Conclusión

Gracias por leer. A pesar de que los trabajos de cron sólo parecen como una herramienta sólo para los administradores de sistemas, en realidad son relevantes para muchos tipos de aplicaciones web.