2

I wrote this code to echo a greeting depending on what time of day it is, but when I run it it doesn't show any errors but doesn't echo anything to the command line either. To try to troubleshoot I commented out everything and echoed just the time variable, which worked fine. So, what am I doing wrong?!

#!/bin/bash


time=$(date +%H)

case $time in
#check if its morning
    [0-11] ) echo "greeting 1";;

#check if its afternoon
    [12-17] ) echo "greeting 2";;

#check if its evening
    [18-23] ) echo "greeting 3"
esac

3 Answers 3

6

[...] introduces a character class, not an integer interval. So, [18-23] is identical to [138-2], which is the same as [13], as there's nothing between 8 and 2.

You can use the following as a fix:

case $time in
#check if its morning
    0?|1[01] ) echo "greeting 1";;

#check if its afternoon
    1[2-7] ) echo "greeting 2";;

#check if its evening
    1[89]|2? ) echo "greeting 3"
esac
2
  • Ahh i hadn't realised that. So is there any way to use a case statement with an integer interval or should i use a different structure?
    – user193369
    Oct 4, 2016 at 17:54
  • @user193369: Check the update.
    – choroba
    Oct 4, 2016 at 17:55
3

I'd use bash arithmetic evaluation instead of pattern matching.

hour=$(date +%_H)
if   ((  0 <= hour && hour <= 11 )); then echo 1
elif (( 12 <= hour && hour <= 17 )); then echo 2
else echo 3
fi

The only thing you have to be careful of is when the hour is "08" or "09" -- those are invalid octal numbers. So you have to get date to give you the hour without a leading zero. Hence the format %_H

0

[] doesn't use numeric ranges, it uses character ranges. What you have there is something that matches the character "0" or "1", the characters "1" and "7", and the characters "1" and "3". (bash completely ignores the malformed ranges 2-1 and 8-2. They are malformed because they aren't increasing.) Also you need a final ;; and a *) would be preferable to catch logic errors such as this one. I recommend you use a cascade of if statements for this:

if [ "$time" -ge 0 ] && [ "$time" -le 11 ]; then
    echo Greeting 1
elif [ "$time" -ge 12 ] && [ "$time" -le 17]; then ...
1
  • i noticed the missing pieces, and i might try using if statements for this instead, thankyou so much for the help!
    – user193369
    Oct 4, 2016 at 18:06

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .