1

This question already has an answer here:

I need to think of a command that I'll execute a different command on uneven days.

marked as duplicate by Tomasz, roaima, Jeff Schaller, Rui F Ribeiro, user4556274 Jan 16 '18 at 22:34

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • 3
    Uneven? Odd? What's the actual problem here? – muru Jan 16 '18 at 10:17
  • You should probably mention whether you want the parity of the day as a day-of-month or day-of-year (e.g. is February 1st odd because it's the 1st day of the month, or even because it's the 32nd day of the year?) – Aaron Jan 16 '18 at 13:40
  • 1
    Also, if you run a command on "uneven/odd days of the month", it's going to run two days in a row sometimes - the 31st, then again on the 1st. Is that what you really want? Even if you base it off of "day of the year", it's going to run twice in a row because 365 is odd. – JPhi1618 Jan 16 '18 at 16:10
  • 2
    This is very vaguely worded. Under what circumstances do you want one of these commands to run at all? Is this something you'd want scheduled to run automatically, to happen when you log in to your shell, or what? – Monty Harder Jan 16 '18 at 16:26
11

As a normal user, run crontab -e to edit your crontab. In that crontab enter:

00 12 1-31/2 * * /path/to/the/command_for_odd_days
00 12 2-30/2 * * /path/to/the/command_for_even_days

For those commands to be run at 12:00 (noon) every day.

If you're administrator on the machine, you can instead create a:

/etc/cron.d/myservice

file, with a similar content, except that you need to specify which user the commands should run as.

00 12 1-31/2 * * someuser /path/to/the/command_for_odd_days
00 12 2-30/2 * * someuser /path/to/the/command_for_even_days

Run man 5 crontab to learn more about the format of those crontabs.

The 1-31/2 syntax (for days between 1 and 31, every two days) should be recognised by most modern cron implementations including all those available on your Ubuntu system. If you come across an ancient system where it's not supported, you can replace it with 1,3,5,7,...,29,31.

9

The %e format specifier of the date utility will give you the day of the month as an integer between 1 and 31 (with a leading space for days 1 to 9, but that's harmless when used inside arithmetic expansions):

day=$( date +%e )

To test whether this number is odd or even:

if [ "$(( day % 2 ))" -eq 0 ]; then
    # $day is even
else
    # $day is odd
fi

Turning it into a shell function:

run_command () (
    day=$( date +%e )

    if [ "$(( day % 2 ))" -eq 0 ]; then
        # $day is even
        some_command_on_even_days
    else
        # $day is odd
        other_command_on_odd_days
    fi
)

This would go in your shell initialization file (e.g. $HOME/.bashrc for bash), and you would then call it with

run_command

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