14

crontab(5) defines the following fields:

       field         allowed values
       -----         --------------
       minute        0-59
       hour          0-23
       day of month  1-31
       month         1-12 (or names, see below)
       day of week   0-7 (0 or 7 is Sun, or use names)

and explains:

 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 every other hour (the alternative in the V7 standard is
 ``0,2,4,6,8,10,12,14,16,18,20,22'').

So, no biweekly Jobs, as far as my understanding goes. I'm quite sure there are workarounds, what are yours? Or did I miss something?

3

7 Answers 7

12

Many crons (you didn't specify which you're using) support ranges. So something like

0 0 1-7,15-21 * 3

Would hit the first and third wednesdays of the month.

Note: Don't use this with vixie cron (included in RedHat and SLES distros), as it makes an or between the day-of-month and day-of-week fields instead of an and.

4
  • this is slightly more elegant than the "do it in the script" method, but remember to add a comment to your crontab (general rule of thumb: if you have more than one - or / involved it's probably worth commenting to describe the schedule)
    – voretaq7
    Jul 4, 2012 at 3:18
  • 2
    I suspect this is wrong; it will cause the job to be run on the 1st-7th, and 15-21st, of each month, and every Wednesday as well. This from man 5 crontab: "The day of a command’s execution can be specified by two fields — day of month, and day of week. If both fields are restricted (ie, aren’t * ), the command will be run when either field matches the current time. For example, "30 4 1,15 * 5" would cause a command to be run at 4:30 am on the 1st and 15th of each month, plus every Friday" (my emphasis).
    – MadHatter
    Oct 10, 2014 at 14:32
  • 2
    Actually, that depends on which cron daemon you are using. Your entry seems to be from vixie cron (included in RedHat distros). From "man crontab" on dillo's cron (Slackware): If you specify both a day in the month and a day of week, *it will be interpreted as the Nth such day in the month*. Still, a scripted solution (calculating week number) looks like the only portable solution.
    – AlvaroGMJ
    Jan 26, 2015 at 14:13
  • Even if it evaluate with "and", this will be wrong. Every month, the first day is different. If you really want to do biweekly, sometimes, the 2nd Wednesday can also be between 8-15. Every now and then, this will skip 1 wednesday.
    – tasomaniac
    May 7, 2021 at 11:25
9

You can have the thing run by cron every wednesday, then have the thing run decide if it is an even week or an odd week. for example:

#!/bin/bash
week=$(date +%U)
if [ $(($week % 2)) == 0 ]; then 
    echo even week
else 
    echo odd week
fi
4
  • This is a nice solution, however, doesn't really answer the question itself - I'd prefer not to taint the thing with schedule logic. Maybe I can integrate this with the link @Somantra gave.
    – Roman
    Jul 3, 2012 at 16:28
  • Alright, I must admit: this is the best solution so far. The link that @Somantra gave achieves the same results unecessarily complex IMHO (counting with UNIX time), but adding your approach directly to the cronjob (instead of into the script) in the same style makes it quite elegant.
    – Roman
    Jul 30, 2012 at 13:41
  • This breaks in the year 2020 because it has 53 weeks. Ex: If your cron was scheduled to run bi weekly on Dec 31st, it would run on Dec 31, 2020 (53rd week) and Jan 4th, 2020 (1st week).
    – mad_fox
    Nov 23, 2018 at 12:51
  • This will break on the 8th and 9th weeks. date output week numbers with zero padding ahead of single digit week numbers (00..09). bash interprets numbers with leading zero as octal. 08 and 09 are not valid octal numbers and thus bash will throw the error "value too great for base". This could be mitigated by trimming off the leading zero, e.g. with - flags in date command date +%-U or with bash parameter expansion ${week#0}.
    – Lacek
    Jun 23, 2021 at 2:23
4

If your needs aren't literally bi-weekly, you could simply run the cronjob on the 1st and 15th of the month:

15 8 1,15 * * /your/script.sh

Which runs at 8:15 a.m. on the first and fifteenth of each month regardless of the day of the week.

1
  • say, I'm doing this on a laptop and it happened to be shutdown at 8:15 am. What would I do to make sure it runs once on that day?
    – Bibek_G
    Jun 21, 2020 at 11:15
3

For something that needs to run every other week use this one-liner:

0 0 * * 5 [ `expr \`date +\%V\` \% 2` -eq 0 ] && echo "execute script" 

This particular script is scheduled to run on Fridays. The week to be executed on can be adjusted by using "-eq 0" or "-eq 1"

1

Anacron is a good workaround for the limitations of cron.

  • Anacron has a Recurrence Period parameter which you can set to 14.

period delay job-identifier command

14 15 test.daily /path/to/script.sh

1
  • Unfortunately, anacron can't be used. Forgot to mention that.
    – Roman
    Jul 3, 2012 at 17:41
0

#Initially create a biweek.txt with the value of 0 inside of it

!/bin/bash

path_biweek=/home/kali/Automate/paystub/biweek.txt; path_paystub=/home/kali/Automate/paystub/paystub.py;

status=$(cat $path_biweek); echo "status = $status"

if [ $status -eq 1 ] then echo 0|tee $path_biweek; status=$(cat $path_biweek); echo "status = $status"; sudo python3 $path_paystub

elif [ $status -eq 0 ] then echo 1|tee $path_biweek; status=$(cat $path_biweek); echo "status = $status";

-2

From that explaination setting 3/2 on the week field should run the task on every other wednesday - its implicit, but i think doable.

3
  • no, this is equivalent to for(int i=3; i <=3 ; i+=2) {} since it is only going through this once, it doesn't matter if the "step" is 1 or 2.
    – stew
    Jul 3, 2012 at 15:43
  • What @stew said. Also, there's no "week field".
    – Roman
    Jul 3, 2012 at 16:30
  • By week field, i mean the "Day of week field' Jul 4, 2012 at 0:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.