how to set cronjob for 2 days? [closed]

Solution 1:

From here:

Cron also supports 'step' values.

A value of */2 in the dom field would mean the command runs every two days and likewise, */5 in the hours field would mean the command runs every 5 hours. e.g.

* 12 10-16/2 * * root backup.sh

is the same as:

* 12 10,12,14,16 * * root backup.sh

So I think you want 0 0 */2 * *.

What you've got (0 0 2 * *) will run the command on the 2nd of the month at midnight, every month.

p.s. You seem to have an extra asterisk in your answer. The format should be:

minute hour dom month dow user cmd

So your extra asterisk would be in the user field. Is that intended?

Solution 2:

Disclaimer: this is a copy of my deleted answer here. I do believe this question is more canonical, and my answer fits better here.

There are two ways this question can be interpreted.

  • I would like to schedule a cron job every second day of the month.
  • I would like to schedule a cron job every two days.

These are two completely different cases because of the number of days there are in a month.

I would like to schedule a cronjob every second day of the month.

For this we use the combination of defining a range and a step value:

man 5 crontab: Step values can be used in conjunction with ranges. Following a range with /<number> specifies skips of the number's value through the range. For example, 0-23/2 can be used in the 'hours' field to specify command execution for every other hour (the alternative in the V7 standard is 0,2,4,6,8,10,12,14,16,18,20,22). Step values are also permitted after an asterisk, so if specifying a job to be run every two hours, you can use */2.

See the following examples:

# 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
  0  0  */2    *  *   command1
  0  0  2-31/2 *  *   command2
  *  *  */2    *  *   command3
  • command1 will be executed at 00:00 on every odd-numbered day (default range with step 2, i.e. 1,3,5,7,...,31)
  • command2 will be executed at 00:00 on every even-numbered day (i.e. 2,4,6,8,...,30)
  • command3 is an often made mistake. This will run on every minute of every odd-numbered day.

Note: It should be understood that in this approach command1 will run on both January 31st and February 1st (2 consecutive days)

Note: It should be understood that in this approach command2 will skip both January 31st and February 1st and will run only 3 days later.

I would like to schedule a cronjob every second day (starting from day X)

Here it gets more interesting. The notes above already demonstrated the problem with months having an odd number of days.

The quick way to think would be to evaluate the day of the year:

% date -d "2018-01-31" '+%j'
031
% date -d "2018-02-01" '+%j'
032

and you could easily investigate if it is an odd or even number. However, When doing this, you have again a problem on December 31st and January 1st in a common year (365 days; leap years have 366 days). This can be resolved when you have a continuous counter from a given day. Enter UNIX time stamp, the total seconds since 1970-01-01 00:00:00 UTC.

% date -d "2018-12-31" '+%s %j'                                                                                                                                                                                                               
1546214400 365
% date -d "2019-01-01" '+%s %j' 
1546300800 001
% date -d "2019-12-31" '+%s %j'                                                                                                                                                                                                               
1577750400 365
% date -d "2020-01-01" '+%s %j'                                                                                                                                                                                                               
1577836800 001

For a cronjob to run command4 only every second day at 00:00 and command5 every third day at 00:00 starting from "2018-03-14", 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
  0  0  *  *  *   daytestcmd 2 && command4
  0  0  *  *  *   daytestcmd 3 20180314 && command5

with daytestcmd defined as

#!/usr/bin/env bash
# get start time in seconds
start=$(date -d "${2:-@0}" '+%s')
# get current time in seconds
now=$(date '+%s')
# get the amount of days (86400 seconds per day)
days=$(( (now-start) /86400 ))
# set the modulo
modulo=$1
# do the test
(( days >= 0 )) && (( days % modulo == 0))

Remark: UNIX time is given in UTC. If your cron runs in a different time-zone which is influenced by daylight saving time, it is advisable not to run the command between 2 and 3 o'clock. This could skip the command or run the command twice (depending if the time jumps forward or backwards)

Remark: UNIX time is not influenced by leap seconds

Solution 3:

If you want to use the crontab -e command, try this time pattern:

0 1 */2 * * command_to_execute

Or, you can try SetCronJob for a web based solution. You can easily create cron jobs every 2 days with the second creating row.