-1

I want to run a command every other Tuesday at 05.15am. Is there a way to do this?

Kusalananda
  • 333,661
x1Bolt
  • 1
  • https://crontab.guru – admstg Mar 23 '23 at 10:37
  • 1
    @admstg How does that help? – Kusalananda Mar 23 '23 at 10:43
  • I tried this: # m h dom mon dow command 15 05 */14 * 2 /bin/ls but I'm not sure it is working, or not, because the */8 valid too. – K-attila- Mar 23 '23 at 10:53
  • I will come back two weeks later, it is exciting :). 15 11 */14 * 4 /bin/echo "Hopp" >>/tmp/cronchk15 11 /8 4 /bin/echo "HippHopp" >>/tmp/cronchk – K-attila- Mar 23 '23 at 10:56
  • 1
    @K-att- That first schedule would run every 14th day of the month, if that happens to be a Tuseday. – Kusalananda Mar 23 '23 at 11:00
  • So sad. Thank you. – K-attila- Mar 23 '23 at 11:01
  • I tried... Nothing happened => bad way. less /tmp/cronchk /tmp/cronchk: No such file or directory Thank you @Kusalandra, again. – K-attila- Mar 23 '23 at 11:51
  • @Kusalananda: It's not every 14th day of the month, it's every time the day (of the month) is divisible by 14, i.e. the 0th (doesn't really occur), the 14th and the 28th. Except at the end of February (in non-leap years) there's more than 14 days between the 28th of one month and the 14th of the next. The approach in your answer is much better. – Henrik supports the community Mar 23 '23 at 12:21
  • @Henriksupportsthecommunity That's what I said, every 14th day of the month, i.e. the 14th and 28th of every month, but also with the additional restriction that these dates must be Tuesdays for the job to trigger. EDIT: The Crontab Guru says that's actually the 1st, 15th and 29th of every month for months that have those days, if they are Tuesdays. – Kusalananda Mar 23 '23 at 12:46
  • @Kusalananda I believe the Guru is wrong. man -s 5 crontab says it runs on the 1st, 15th, 29th and every Tuesday (but not twice on the same day). See "Note: 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 (i.e., aren't ), the command will be run when either* field matches the current time." The */n notation is a skip (not a modulus), and the implicit start for the day of month is 1. – Paul_Pedant Mar 23 '23 at 20:32

1 Answers1

1

The cron schedule for running a job at 05:15 on Tuesdays is

15 5 * * 2

or use the day name (this may not be supported everywhere),

15 5 * * tue

The easiest way to get your command to run every second time this schedule triggers it is to let the cron job keep its state as a temporary file. If the file exists, it is removed, but the job does nothing else. If the file does not exist, the command is run, and then the job creates the file.

So your schedule could look like this:

15 5 * * 2 if [ -e /tmp/statefile ]; then rm -f /tmp/statefile; else cmd; touch /tmp/statefile; fi

Obviously (?) this would be cleaner if the business logic was encapsulated in a shell script that was triggered by the cron schedule:

15 5 * * 2 /some/path/cron-wrapper

The cron-wrapper shell script could look something like this:

#!/bin/sh

statefile=/tmp/statefile

if [ -e "$statefile" ]; then rm -f "$statefile" exit fi

cmd # the command we want to run

touch "$statefile"

Note that this does not take care to preserve the exit status of the command (cmd in the above examples). If you need to do that to e.g. let cron inform you of a failed run, then ensure that your wrapper script exits with the exit status of the command:

#!/bin/sh

statefile=/tmp/statefile

if [ -e "$statefile" ]; then rm -f "$statefile" exit fi

cmd # the command we want to run err=$?

touch "$statefile"

exit "$err"

The exact logic that you want to use here depends on your requirements. Do you, for example, want to avoid creating the state file if the command fails? You may also want to create the state file elsewhere in a safe location that is unlikely to be cleared out by maintenance scripts and where it is unlikely to overwrite other data or be overwritten by other projects running on the same machine.

The other way to do this is by employing some form of date calculations, as described in the currently accepted answer to a similar question: Run a script via cron every other week

Kusalananda
  • 333,661