¿Cómo ejecutar un cronjob cada X minutos?

94

Estoy ejecutando un script PHP en un cronjob y quiero enviar correos electrónicos cada 5 minutos.

Mi trabajo cron actual (crontab):

10 * * * * /usr/bin/php /mydomain.in/cromail.php > /dev/null 2>&1

El cronmail.php es el siguiente:

<?php
$from = 'D'; // sender
$subject = 'S';
$message = 'M';
$message = wordwrap($message, 70);
mail("[email protected]", $subject, $message, "From: $from\n");
?>

Pero no he recibido un correo electrónico en 30 minutos con esta configuración.

Savan Paun
fuente
2
su ruta absoluta probablemente no sea correcta
Rene Pot
por favor sugierame la ruta correcta mi archivo php cromail.php está en el directorio raíz - mydomain.in/cromail.php
Savan Paun
A veces, php-cli no quiere funcionar solo porque no ha configurado la zona horaria actual en su php.ini, incluso si no usa date.
T00rk
¿Es cromail.phpo cronmail.php?
Biffen
cromail.php solo para pruebas
Savan Paun

Respuestas:

165

En un crontabarchivo, los campos son:

  • minuto de la hora.
  • hora del día.
  • día del mes.
  • mes del año.
  • día de la semana.

Entonces:

10 * * * * blah

significa ejecutar blaha los 10 minutos después de cada hora.

Si desea cada cinco minutos, use:

*/5 * * * * blah

es decir, cada minuto pero solo cada quinto, o:

0,5,10,15,20,25,30,35,40,45,50,55 * * * * blah

para cronejecutables más antiguos que no entienden la */xnotación.

Si aún parece que no funciona después de eso, cambie el comando a algo como:

date >>/tmp/debug_cron_pax.txt

y supervise ese archivo para asegurarse de que se escriba algo cada cinco minutos. Si es así, hay algún problema con sus scripts PHP. Si no es así, hay algún problema con tu crondaemon.

paxdiablo
fuente
actualizo * / 5 * * * * mydomain.in/cronmail.php> / dev / null 2> & 1 No recibo correo electrónico
Savan Paun
También utilicé el comando mencionado aquí, pero no funcionaba porque tenía una declaración de devolución después. Asegúrese de no terminar la declaración con return y también una nota, cuando se crea un nuevo cron, muestra el mensaje "crontab: instalando un nuevo crontab".
maldito demonio
31

Su CRON debería verse así:

*/5 * * * *

CronWTF es realmente útil cuando necesita probar su configuración CRON.

Podría ser una buena idea canalizar la salida a un archivo de registro para que pueda ver si su secuencia de comandos también arroja errores, ya que no los verá en su terminal.

También intente usar un shebang en la parte superior de su archivo PHP, para que el sistema sepa dónde encontrar PHP. Como:

#!/usr/bin/php

de esa manera puedes llamar a todo así

*/5 * * * * php /path/to/script.php > /path/to/logfile.log

Gary Jones
fuente
actualizo * / 5 * * * * mydomain.in/cronmail.php> / dev / null 2> & 1 No recibo correo electrónico
Savan Paun
2
¿Ha intentado ejecutar el script manualmente y no a través del cron? En realidad, el problema puede estar en el propio script.
Gary Jones
5

Está configurando su cron para que se ejecute en el décimo minuto cada hora.
Para configurarlo para que every 5 minscambie a*/5 * * * * /usr/bin/php /mydomain.in/cronmail.php > /dev/null 2>&1

Justinas
fuente
actualizo * / 5 * * * * midominio.in/cronmail.php> / dev / null 2> & 1 No recibo correo electrónico
Savan Paun
@ user3705511 Olvidó ejecutarlo a través de php - usr/bin/phpparte faltante
Justinas
agregado * / 5 * * * * usr / bin / php / mydomain.in / cronmail.php> / dev / null 2> & 1 pero aún no recibe correo electrónico
Savan Paun
@ user3705511*/5 * * * * /usr/bin/php /mydomain.in/cromail.php > /dev/null 2>&1
Justinas
actualizado pero aún sin recibir correo electrónico * / 5 * * * * usr / bin / php / mydomain.in/cronmail.php> / dev / null 2> & 1
Savan Paun
5

Si desea ejecutar un cron cada nminuto, hay algunas opciones posibles según el valor de n.

n divide 60 (1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 30)

Aquí, la solución es sencilla haciendo uso de la /notación:

# Example of job definition:
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7)
# |  |  |  |  |
# *  *  *  *  *   command to be executed
m-59/n  *  *  *  *   command

En lo anterior, nrepresenta el valor ny mrepresenta un valor menor que no *. Esto ejecutará el comando en los minutosm,m+n,m+2n,...

n NO divide 60

Si nno divide 60, no puede hacerlo limpiamente con cron, pero es posible. Para hacer esto, necesita poner una prueba en el cron donde la prueba verifica la hora. Esto se hace mejor cuando se mira la marca de tiempo de UNIX, el total de segundos desde 1970-01-01 00:00:00 UTC. Digamos que queremos comenzar a ejecutar el comando la primera vez que Marty McFly llegó a Riverdale y luego repetirlo cada nminutos más tarde.

% date -d '2015-10-21 07:28:00' +%s 
1445412480

Para que un cronjob se ejecute cada 42minuto después de `2015-10-21 07:28:00 ', el crontab se vería así:

# Example of job definition:
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7)
# |  |  |  |  |
# *  *  *  *  *   command to be executed
  *  *  *  *  *   minutetestcmd "2015-10-21 07:28:00" 42 && command

con minutetestcmddefinido como

#!/usr/bin/env bash
starttime=$(date -d "$1" "+%s")
# return UTC time
now=$(date "+%s")
# get the amount of minutes (using integer division to avoid lag)
minutes=$(( (now - starttime) / 60 ))
# set the modulo
modulo=$2
# do the test
(( now >= starttime )) && (( minutes % modulo == 0 ))

Observación: el tiempo UNIX no se ve afectado por los segundos intercalares

Observación: cron no tiene una precisión inferior a un segundo

kvantour
fuente
La m/nnotación no parece funcionar en mis sistemas (Debian 9, Ubuntu 16.04). Solo */nfunciona. Por ejemplo, 5/5o 4/10ceda Error: bad minute; while reading /etc/crontabsyslog (en Ubuntu con cron v. 3.0pl1-128ubuntu2). ¿Se ha abandonado esta notación m / n o solo está disponible en algunos sistemas?
mivk
@mivk Gracias por señalar esto. Este fue un error de mi parte. Debería haber leído m-59/n. Solo un rango puede tener un tamaño de paso. (ver man 5 crontab). He actualizado la respuesta
kvantour
3

2 pasos para verificar si un cronjob está funcionando:

  1. Inicie sesión en el servidor con el usuario que ejecuta el cronjob
  2. Ejecute manualmente el comando php:

    / usr / bin / php /mydomain.in/cromail.php

Y verifique si se muestra algún error

Paul Giragossian
fuente
3
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# |  |  |  |  |
# *  *  *  *  * user-name  command to be executed

Para establecer x minutos, necesitamos establecer x minutos en el primer argumento y luego la ruta de su script

Por 15 minutos

*/15 * * * *  /usr/bin/php /mydomain.in/cromail.php > /dev/null 2>&1
Shakeel Javeed
fuente
1
Esto NO ejecuta las tareas CADA x (15) minutos. Lo ejecuta en x (1) minutos después de cada hora completa.
silverdr