0

I'm setting up a cron job to suspend and wake a server at certian times.

I'm using two commands. One to be run from mondays to thursdays:

rtcwake -m mem -t $(date +%s -d "08:00")

And another one to be run on fridays:

rtcwake -m mem -t $(date +%s -d "monday 08:00")

I wonder if it's possible to make this separation unnecessary. If date could understand a statement like next weekday 08:00, it'd simplify things a lot.

I wasn't able to find if this is actually possible or what syntax should I use.

I basically want to avoid my server waking up on saturdays and sundays.

2
  • Have you considered having two separate cron jobs?
    – Jeff Schaller
    Aug 9, 2018 at 19:12
  • Note - the week start day varies by locale.
    – fpmurphy
    Jan 5, 2021 at 15:15

3 Answers 3

1

If you are willing to use ksh93, you can easily calculate "next weekday 0800", which I assume really means first business day of the next week. Assuming you are located in the USA, the first business day of the week is typically a Monday.

$ printf "%T\n"                
Tue Jan  5 16:04:37 GMT 2021
$ printf "%T\n" "0 8 * * 1"
Mon Jan 11 08:00:00 GMT 2021
$ printf "%(%s)T\n" "0 8 * * 1"
1610352000
$ 

The key to how the above works is the string "0 8 * * 1" which is represents the five crontab time and date fields. See crontab(5) manpage for details of these fields.

Not many people are aware that ksh93 time formatting recognizes specific parts of this quasi-crontab entry format, and outputs the corresponding date in the designated format.

0

You may want to try

date +%s -d"$(( ( $(date +%w)==5 )?3:1 ))days 8:00"

EDIT: to answer your comment: date +%w yields the day of week, which then is evaluated by a "conditional operator" (expr?expr:expr): if expr1 evaluates to TRUE, evaluate and use expr2, else expr3. So, on Friday, we have day 5, and run date +%s -d"3days 8:00, on the other days date +%s -d"1days 8:00.

4
  • 1
    Note that in a cron job specification, the % character has to be escaped as \%.
    – Kusalananda
    Aug 9, 2018 at 10:09
  • Hmm - yes, thanks - but not in his/her question above...
    – RudiC
    Aug 9, 2018 at 10:13
  • "I'm setting up a cron job"...
    – Kusalananda
    Aug 9, 2018 at 10:14
  • Thanks! Could you explain a bit how does this code work?
    – unfa
    Aug 9, 2018 at 10:18
0

Here's what I came up with for a similar need. Way more verbose than the other answer but it may make it a bit more obvious what it's doing.

last_workday() {
    from_date="${@:-today}"
    day_of_week=$(date +%w --date="${from_date}")

    if [ ${day_of_week} = "0" ] ; then
        look_back=2
    elif [ ${day_of_week} = "1" ] ; then
        look_back=3
    else
        look_back=1
    fi

    date -d "${from_date} - ${look_back} day" +'%Y/%m/%d'
}

next_workday() {
    from_date="${@:-today}"
    day_of_week=$(date +%w --date="${from_date}")
    if [ ${day_of_week} = "5" ] ; then
        look_forward=3
    elif [ ${day_of_week} = "6" ] ; then
        look_forward=2
    else
        look_back=1
    fi

    date -d "${from_date} + ${look_forward} day" +'%Y/%m/%d'
}

for i in $(seq 16); do
    now=$(date +'%Y/%m/%d' --date="today + ${i} day")
    prev=$(last_workday "${now}")
    next=$(next_workday "${now}")
    echo "${now}:  ${prev} ${next}"
done

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.