There are many good answers here. Based upon the comments, I see quite a bit of confusion and frustration. My intention with this answer is to not only answer the OPs question How to instruct cron to execute a job every second week?, but also clear up some confusion for folks who may read this in the future.

**TL;DR:**

The crontab entry look like this:

```
<code>\<minute\> \<hour\> * * \<Day of Week\> expr \\( $( date+\\%s ) \\/ 604800 \\% 2 \\) > /dev/null && \<command to run on odd weeks\> || \<command to run on even weeks\></code>
```

**Crontab Entries:**

All crontab entries [made with `crontab -e`

] have this format, per the man page:

1: The Minute of the hour to execute [command]

Range: 0-59

2: The Hour of the Day to execute [command]

Range: 0-23
3: The Day of the Month to execute [command]

Range: 1-31

4: The Month to execute [command]

Range: 1-12

5: The Day of Week to execute [command]

Range: Check your man page, could be 0-6, 1-7 or 0-7

6: command to execute

Note, there are also @ values, which I will not discuss here.

Some versions of *nix allow for expressions:

`*/2`

= every even number in range

`1 + */2`

= every odd number in range

`1,15`

= First & 15th

`2-8`

= Second through the Eighth (inclusive)

Some versions allow for the Human Readable words also, such as February or Wednesday.

For Month, */2 will execute on Feb, Apr, Jun, Aug, Oct, Dec.

For Days of Week, */2 will run every even day -- check your man page to see how the Days of Week are numbered. Tue/2 is NOT a valid expression.

**Human Readable (Calendar) Woes**

Some constants you need to know:

There are 365.2464 *days* in a year (For convenience, we'll round to 365).

There are 12 *months* in a year.

There are 7 *days* in a week.

There 86,400 *seconds* in a day.

Therefore,

1 month is 4-1/3 weeks

[i.e. 3 months is 13 weeks]

1 year is 52-1/7 weeks

*The bane of calendar math:*

Semi-Monthly = every half month = 2x/month = 24 times per year.

Bi-weekly = every other week (fortnightly) = 26 times per year.

Note: These terms are often mis-used.

Some years have 51 weeks, some have 53, most have 52. If My cron runs every odd week ( `date +%W`

mod 2), and the year has 51 or 53 weeks, it will also run the following week, which is week 1 of the new year. Conversely, if my cron runs every even week, it will skip 2 weeks. Not what I want.

CRON can support semi-monthly, it cannot support bi-weekly!
Semi-monthly:

The first of the month will always fall between the 1st & 7th. The second half of the week will always occur between the 15th and the 21st.

Semi-monthly would have 2 values, one in the first half and the other in the second half of the month. Such as:

`2,16`

**Unix Time**

At a very high level, *nix time is 2 values:

`date +%s`

= Number of Seconds since Epoch (01/01/1970 00:00:00)

`date +%N`

= fractional seconds (in Nano seconds)

Therefore, time in *nix is `date +%s.%N`

*Nix uses epoch time. The /etc/shadow file contains the date of last password change. It is the integer portion of %s divided by 86,400.

**Factino**

The GPS satellites measure time as "Number of weeks since epoch time" and "(fractional) seconds into the week.

Note: Epoch weeks are independent of years. It does not matter if the year has 51, 52, or 53 weeks. Epoch weeks never roll over.

**Bi-Weekly Time Algorithm**

In *Nix date +%W is week number of the *year*, not epoch week. *nix does not have an epoch week value, but it can be computed.

Epoch Week = Integer( Epoch Seconds / Seconds_per_Day / Days_per_Week )

Fortnightly = Epoch_Week Modulo 2

The Fortnightly value will always be 0 or 1, thus, running the command when Fortnightly = 0 runs on every even week, and 1 = every odd week.

**Computing Fortnightly)**

The first way (bc):

`date +"%s / 604800 % 2" | bc`

This will generate "[Epoch Seconds] / 604800 % 2"

That answer is then sent to bc, a basic calculator, which does the math and echoes the answer to STDOUT and any errors to STDERR.

The return code is 0.

The second way (expr):

In this case, send the expression to expr and let it do the math
`expr $( date +%s ) / 604800 % 2`

The expr command does the math, echoes the answer to STDOUT, errors to STDERR.
The return code is 1 if the answer is 0, otherwise, the return code is 0.

In this manner, I don't care what the answer is, only the return code. Consider this:

```
$ expr 1 % 2 && echo Odd || echo Even
1
Odd
$ expr 2 % 2 && echo Odd || echo Even
0
Even
```

Since the result doesn't matter, I can re-direct STDOUT to /dev/null. In this case, I'll leave STDERR incase something unexpected happens, I'll see the error message.

**Crontab Entry**

In crontab, the percent sign and the parenthesis have special meanings, so they need to be escaped with a backslash (\).

First, I need to decide if I want to run on Even weeks or odd weeks. Or, perhaps, run Command_O on Odd weeks and command_E on even weeks. Then, I need to escape all the special characters.

Since the expr only evaluates WEEKS, it is necessary to specify a particular day of the week (and time) to evaluate, such as every Tuesday at 3:15pm. Thus, the first 5 files (the Time Entry) of my crontab entry will be:

`15 3 * * TUE`

The first part of my cron command will be the expr command, with STDOUT sent to null:

```
<code>expr \\( $( date+\\%s ) \\/ 604800 \\% 2 \\) > /dev/null</code>
```

The second part will be the evaluator, `&&`

or `||`

The Third part will be the command (or script) I want to run. Which looks like this:

```
<code>expr \\( $( date+\\%s ) \\/ 604800 \\% 2 \\) > /dev/null && \<command_O\> || \<command_E\></code>
```

Hopefully, that will clarify some of the confusion

`if [ "$(cat week.txt)" == "1" ]; then echo -n "0">week.txt; dostuff; fi`