Comment exécuter un cronjob toutes les X minutes?

94

J'exécute un script PHP dans un cronjob et je souhaite envoyer des e-mails toutes les 5 minutes

Mon cronjob actuel (crontab):

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

Le cronmail.php est le suivant:

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

Mais je n'ai pas reçu d'email depuis 30 minutes avec cette configuration.

Savan Paun
la source
2
votre chemin absolu n'est probablement pas correct
Rene Pot
s'il vous plaît suggérez-moi le bon chemin que mon fichier php cromail.php est dans le répertoire racine - mydomain.in/cromail.php
Savan Paun
Parfois, php-cli ne veut pas fonctionner simplement parce que vous n'avez pas défini le fuseau horaire actuel dans votre php.ini même si vous n'utilisez pas de date.
T00rk le
Est-ce cromail.phpou cronmail.php?
Biffen le
cromail.php pour les tests uniquement
Savan Paun

Réponses:

165

Dans un crontabfichier, les champs sont:

  • minute de l’heure.
  • heure de la journée.
  • jour du mois.
  • Mois de l'année.
  • jour de la semaine.

Alors:

10 * * * * blah

signifie exécuter blahà 10 minutes toutes les heures.

Si vous voulez toutes les cinq minutes, utilisez soit:

*/5 * * * * blah

c'est-à-dire toutes les minutes mais seulement toutes les cinq, ou:

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

pour les anciens cronexécutables qui ne comprennent pas la */xnotation.

Si cela semble toujours ne pas fonctionner après cela, changez la commande en quelque chose comme:

date >>/tmp/debug_cron_pax.txt

et surveillez ce fichier pour vous assurer que quelque chose est écrit toutes les cinq minutes. Si tel est le cas, il y a un problème avec vos scripts PHP. Sinon, il y a un problème avec votre crondémon.

paxdiablo
la source
Je mets à jour * / 5 * * * * mydomain.in/cronmail.php> / dev / null 2> & 1 Je ne reçois pas d'e
Savan Paun
J'ai également utilisé la commande mentionnée ici, mais cela ne fonctionnait pas car j'avais une déclaration de retour après. Assurez-vous de ne pas terminer l'instruction avec return et aussi une note, quand un nouveau cron est créé, il affiche le message "crontab: installation d'un nouveau crontab".
damndemon
31

Votre CRON devrait ressembler à ceci:

*/5 * * * *

CronWTF est vraiment utile lorsque vous devez tester vos paramètres CRON.

Cela peut être une bonne idée de diriger la sortie dans un fichier journal afin que vous puissiez voir si votre script génère également des erreurs - car vous ne les verrez pas dans votre terminal.

Essayez également d'utiliser un shebang en haut de votre fichier PHP, afin que le système sache où trouver PHP. Tel que:

#!/usr/bin/php

comme ça tu peux appeler tout ça comme ça

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

Gary Jones
la source
Je mets à jour * / 5 * * * * mydomain.in/cronmail.php> / dev / null 2> & 1 Je ne reçois pas d'e
Savan Paun
2
Avez-vous essayé d'exécuter le script manuellement et non via le cron? Le problème vient peut-être du script lui-même.
Gary Jones
5

Vous configurez votre cron pour qu'il s'exécute à la 10e minute par heure.
Pour le configurer pour qu'il every 5 minsdevienne*/5 * * * * /usr/bin/php /mydomain.in/cronmail.php > /dev/null 2>&1

Justinas
la source
Je mets à jour * / 5 * * * * mydomain.in/cronmail.php> / dev / null 2> & 1 Je ne reçois pas d'e
Savan Paun
@ user3705511 Vous avez oublié de l'exécuter via php - usr/bin/phppartie manquante
Justinas
ajouté * / 5 * * * * usr / bin / php / mydomain.in / cronmail.php> / dev / null 2> & 1 mais ne reçoit toujours pas d'email
Savan Paun
@ user3705511*/5 * * * * /usr/bin/php /mydomain.in/cromail.php > /dev/null 2>&1
Justinas
mis à jour mais toujours pas reçu d'e-mail * / 5 * * * * usr / bin / php / mydomain.in/cronmail.php> / dev / null 2> & 1
Savan Paun
5

Si vous souhaitez exécuter un cron toutes les nminutes, il existe quelques options possibles en fonction de la valeur de n.

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

Ici, la solution est simple en utilisant la /notation:

# 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

Dans ce qui précède, nreprésente la valeur net mreprésente une valeur inférieure à nou *. Cela exécutera la commande aux minutesm,m+n,m+2n,...

n ne divise PAS 60

Si nne divise pas 60, vous ne pouvez pas le faire proprement avec cron, mais c'est possible. Pour ce faire, vous devez mettre un test dans le cron où le test vérifie l'heure. Cela est mieux fait lorsque vous regardez l'horodatage UNIX, le nombre total de secondes depuis 1970-01-01 00:00:00 UTC. Disons que nous voulons commencer à exécuter la commande la première fois lorsque Marty McFly est arrivé à Riverdale, puis la répéter toutes les nminutes plus tard.

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

Pour qu'un cronjob s'exécute toutes les 42nd minutes après `2015-10-21 07:28:00 ', le crontab ressemblerait à ceci:

# 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

avec minutetestcmddéfini comme

#!/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 ))

Remarque: l' heure UNIX n'est pas influencée par les secondes intercalaires

Remarque: cron n'a pas de précision inférieure à la seconde

kvantour
la source
La m/nnotation ne semble pas fonctionner sur mes systèmes (Debian 9, Ubuntu 16.04). Fonctionne seulement */n. Par exemple, 5/5ou 4/10donnez Error: bad minute; while reading /etc/crontabdans syslog (dans Ubuntu avec cron v. 3.0pl1-128ubuntu2). Cette notation m / n a-t-elle été abandonnée ou n'est-elle disponible que dans certains systèmes?
mivk le
@mivk Merci d'avoir signalé cela. C'était une erreur de mon côté. Il aurait dû lire m-59/n. Seule une plage peut avoir une taille de pas. (voir man 5 crontab). J'ai mis à jour la réponse
kvantour
3

2 étapes pour vérifier si un cronjob fonctionne:

  1. Connectez-vous sur le serveur avec l'utilisateur qui exécute le cronjob
  2. Exécutez manuellement la commande php:

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

Et vérifiez si une erreur est affichée

Paul Giragossian
la source
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

Pour définir pendant x minutes, nous devons définir x minutes dans le 1er argument, puis le chemin de votre script

Pendant 15 minutes

*/15 * * * *  /usr/bin/php /mydomain.in/cromail.php > /dev/null 2>&1
Javeed Shakeel
la source
1
Cela n'exécute PAS les prises TOUTES les x (15) minutes. Il l'exécute sur x (1) minutes après chaque heure complète.
silverdr