124

I'm running a PHP script in a cronjob and I want to send emails every 5 minutes

My current (crontab) cronjob:

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

The cronmail.php is as follows:

<?php
$from = 'D'; // sender
$subject = 'S';
$message = 'M';
$message = wordwrap($message, 70);
mail("myemail@gmail.com", $subject, $message, "From: $from\n");
?>

But I've not received an email in 30 minutes with this configuration.

Sainan
  • 1,274
  • 2
  • 19
  • 32
Savan Paun
  • 1,723
  • 2
  • 16
  • 24

7 Answers7

206

In a crontab file, the fields are:

  • minute of the hour.
  • hour of the day.
  • day of the month.
  • month of the year.
  • day of the week.

So:

10 * * * * blah

means execute blah at 10 minutes past every hour.

If you want every five minutes, use either:

*/5 * * * * blah

meaning every minute but only every fifth one, or:

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

for older cron executables that don't understand the */x notation.

If it still seems to be not working after that, change the command to something like:

date >>/tmp/debug_cron_pax.txt

and monitor that file to ensure something's being written every five minutes. If so, there's something wrong with your PHP scripts. If not, there's something wrong with your cron daemon.

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
  • i update */5 * * * * mydomain.in/cronmail.php > /dev/null 2>&1 Not receiving email – Savan Paun Sep 09 '14 at 09:22
  • I used the command mentioned here as well, but it was not working because I had a return statement after it. Make sure not to end the statement with return and also a note, when new cron is created it shows "crontab: installing new crontab" message. – damndemon May 15 '20 at 07:26
35

Your CRON should look like this:

*/5 * * * *

CronWTF is really usefull when you need to test out your CRON settings.

Might be a good idea to pipe the output into a log file so you can see if your script is throwing any errors too - since you wont see them in your terminal.

Also try using a shebang at the top of your PHP file, so the system knows where to find PHP. Such as:

#!/usr/bin/php

that way you can call the whole thing like this

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

Gary Jones
  • 451
  • 3
  • 3
7

If you want to run a cron every n minutes, there are a few possible options depending on the value of n.

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

Here, the solution is straightforward by making use of the / 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

In the above, n represents the value n and m represents a value smaller than n or *. This will execute the command at the minutes m,m+n,m+2n,...

n does NOT divide 60

If n does not divide 60, you cannot do this cleanly with cron but it is possible. To do this you need to put a test in the cron where the test checks the time. This is best done when looking at the UNIX timestamp, the total seconds since 1970-01-01 00:00:00 UTC. Let's say we want to start to run the command the first time when Marty McFly arrived in Riverdale and then repeat it every n minutes later.

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

For a cronjob to run every 42nd minute after `2015-10-21 07:28:00', the crontab would look like this:

# 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

with minutetestcmd defined as

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

Remark: UNIX time is not influenced by leap seconds

Remark: cron has no sub-second accuracy

kvantour
  • 25,269
  • 4
  • 47
  • 72
  • The `m/n` notation doesn't seem to work on my systems (Debian 9, Ubuntu 16.04). Only `*/n` works. For example, `5/5` or `4/10` give `Error: bad minute; while reading /etc/crontab` in syslog (in Ubuntu with cron v. 3.0pl1-128ubuntu2). Has this m/n notation been abandoned, or is it only available in some systems? – mivk Jun 29 '19 at 14:46
  • @mivk Thanks for pointing this out. This was a mistake on my side. It should have read `m-59/n`. Only a range can have a step size. (see `man 5 crontab`). I have updated the answer – kvantour Jun 29 '19 at 23:45
6

You are setting your cron to run on 10th minute in every hour.
To set it to every 5 mins change to */5 * * * * /usr/bin/php /mydomain.in/cronmail.php > /dev/null 2>&1

Justinas
  • 41,402
  • 5
  • 66
  • 96
4
# .---------------- 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

To set for x minutes we need to set x minutes in the 1st argument and then the path of your script

For 15 mins

*/15 * * * *  /usr/bin/php /mydomain.in/cromail.php > /dev/null 2>&1
Javeed Shakeel
  • 2,926
  • 2
  • 31
  • 40
  • 1
    This does NOT run the taks EVERY x (15) minutes. It runs it on x (1) minutes after every full hour. – silverdr Feb 01 '18 at 13:25
3

2 steps to check if a cronjob is working :

  1. Login on the server with the user that execute the cronjob
  2. Manually run php command :

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

And check if any error is displayed

0

Try a crontab record like this

*/5 * * * * php /usr/bin/php/mydomain.in/cromail.php
helvete
  • 2,455
  • 13
  • 33
  • 37
POGSNET
  • 45
  • 7