Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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
share|improve this question
up vote 6 down vote accepted

[...] 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
share|improve this answer
    
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 yesterday
    
@user193369: Check the update. – choroba yesterday
    
Brilliant, thanks!!! – user193369 yesterday

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

share|improve this answer

[] 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 ...
share|improve this answer
    
i noticed the missing pieces, and i might try using if statements for this instead, thankyou so much for the help! – user193369 yesterday

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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