LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 06-08-2006, 02:38 PM   #1
Blackout_08
Member
 
Registered: Jan 2004
Posts: 35

Rep: Reputation: 15
Bash if, elif, else not working


Here is my script kind of long. For some reason my else statement never runs and i can't see why. Basically i take a users input YYYYMMDD and run it thru a validator that i made. if it fails i display an error else i want to display a msg. My msg never displays though. Here is my script.

#Checks to see if an argument was passed or if user requires a prompt

if [ ! $1 ]
then
echo "Please enter your birthdate (YYYYMMDD)"
read BIRTHDATE
else
BIRTHDATE=$1
fi

#Assigning the user values into variables: year, month and day
YR=${BIRTHDATE:0:4}
MTH=${BIRTHDATE:4:2}
DAY=${BIRTHDATE:6:2}

#Checking to see if the date entered is exactly 8 characters long
BIRTH_LEN=`expr length $BIRTHDATE = 8`
if [ $BIRTH_LEN = 0 ]
then
echo "You entered `expr length $BIRTHDATE` characters, please enter your birthday in the form YYYYMMDD"

#Checking to see if the date entered contains any non-numeric characters
elif !((BIRTHDATE-1)) 2> /dev/null
then
echo "Your entry contains non-numeric characters, please enter your birthday in the form YYYYMMDD"

#Checking to see if the date entered is a future date
elif [ $BIRTHDATE -gt `date +"%Y%m%d"` ]
then
echo "You entered $BIRTHDATE, which is a future date, please enter your birthdate in the form YYYYMMDD"

#Checking to see if the date is invalid. Looking at months that are 31 days
elif [ $MTH -eq 1 ] || [ $MTH -eq 3 ] || [ $MTH -eq 5 ] || [ $MTH -eq 7 ] || [ $MTH -eq 8 ] || [ $MTH -eq 10 ] || [ $MTH -eq 12 ]
then
if [ $DAY -gt 31 ]
then
echo "You entered $BIRTHDATE, which is an invalid date. Please enter your birthdate in the form YYYYMMDD"
fi

#Checking to see if the date is invalid. Looking at months that are 30 days
elif [ $MTH -eq 4 ] || [ $MTH -eq 6 ] || [ $MTH -eq 9 ] || [ $MTH -eq 11 ]
then
if [ $DAY -gt 30 ]
then
echo "You entered $BIRTHDATE, which is an invalid date. Please enter your birthdate in the form YYYYMMDD"
fi

#Checking to see if the date is invalid. Looking at February and leap years.
elif [ $MTH -eq 2 ]
then
if [ $((YR%400)) -eq 0 ]
then
if [ $DAY -gt 29 ]
then
echo "You entered $BIRTHDATE, which is an invalid date. Please enter your birthdate in the form YYYYMMDD"
fi
elif [ $((YR%4)) -eq 0 ] && [ $((YR%100)) != 0 ]
then
if [ $DAY -gt 29 ]
then
echo "You entered $BIRTHDATE, which is an invalid date. Please enter your birthdate in the form YYYYMMDD"
fi
else
if [ $DAY -gt 28 ]
then
echo "You entered $BIRTHDATE, which is an invalid date. Please enter your birthdate in the form YYYYMMDD"
fi
fi
else
echo "it works"
fi



the else doesn't run. Ne help would be appreciated
 
Old 06-08-2006, 03:04 PM   #2
MensaWater
LQ Guru
 
Registered: May 2005
Location: Atlanta Georgia USA
Distribution: Redhat (RHEL), CentOS, Fedora, CoreOS, Debian, FreeBSD, HP-UX, Solaris, SCO
Posts: 7,075
Blog Entries: 14

Rep: Reputation: 1251Reputation: 1251Reputation: 1251Reputation: 1251Reputation: 1251Reputation: 1251Reputation: 1251Reputation: 1251Reputation: 1251
I'd suggest moving your "It works" AFTER the last "fi" and getting rid of the else. On every other condition that fails add "exit 1" after the error message. By doing this it would only print the "it works" if you hadn't done the "exit 1". The "exit 1" says to exit the script with a return code of 1 (failure - you can use any non zero number - 0 = success).

However rather than having the horribly nested conditionals you have you might want to explore the "case" statement. It is similar to if (ends in esac rather than fi) and is specifically designed to do different functions based on different possible outcomes.
 
Old 06-08-2006, 03:16 PM   #3
Blackout_08
Member
 
Registered: Jan 2004
Posts: 35

Original Poster
Rep: Reputation: 15
I can't use the exit command. Its a restriction i have
 
Old 06-08-2006, 05:16 PM   #4
demon_vox
Member
 
Registered: May 2006
Location: Argentina
Distribution: SuSE 10
Posts: 173

Rep: Reputation: 30
Hi,
I am looking and the code and its hard to follow! I totally agree with jlightner that the nested conditionals are not the best way to go.
Just a detail before I go on, I think (and I say "I THINK" because I haven't tried it) that in the first elif there is missing a couple of [ ]

One thing you could do to find the error is to comment all the ifs and start uncommenting the blocks one by one to see where it stops working.

You could also write diferent functions for each condition so as to decouple a little all the if. So you will save the diferent return codes from the functions in diferent variables and then you wont have so many ifs, and then it is easier to find where the error is.

Hope this is usefull!
 
Old 06-08-2006, 08:08 PM   #5
chrism01
LQ Guru
 
Registered: Aug 2004
Location: Sydney
Distribution: Centos 6.9, Centos 7.3
Posts: 17,417

Rep: Reputation: 2397Reputation: 2397Reputation: 2397Reputation: 2397Reputation: 2397Reputation: 2397Reputation: 2397Reputation: 2397Reputation: 2397Reputation: 2397Reputation: 2397
You may find using [[ ]] instead of [ ] a good idea: http://www.tldp.org/LDP/abs/html/tes...ml#DBLBRACKETS
Also, I think the expr length test should be -eq instead of = ?
Please use code tags when posting code; thank you.
Actually, the whole doc: http://www.tldp.org/LDP/abs/html/index.html is worth reading.
 
Old 06-08-2006, 08:56 PM   #6
osor
HCL Maintainer
 
Registered: Jan 2006
Distribution: (H)LFS, Gentoo
Posts: 2,450

Rep: Reputation: 76
The error occurs because you test for:
  • The month given is supposed to have 31 days
  • The month given is supposed to have 30 days
  • The month given is February

Any valid month you enter will cause the script to do some checks, and bypass the rest of the statement. What you should do instead is to test for:
  • The month given is supposed to have 31 days _AND_ the day given is higher than thirty-one
  • The month given is supposed to have 30 days _AND_ the day given is higher than thirty
  • (The month given is February _AND_ the day given is higher than twenty-nine) _OR_ (the day given is higher than twenty-eight _AND_ the year given is divisible by four _AND (divisible by 400 _OR_ not divisible by 100))

This is just a replacement for your work. In reality, the code needs major cleanup.
 
Old 06-08-2006, 11:57 PM   #7
homey
Senior Member
 
Registered: Oct 2003
Posts: 3,057

Rep: Reputation: 59
This may be a start ...
Code:
#!/bin/bash

if [ ! $1 ]
then
read -p "Please enter your birthdate (YYYYMMDD) " BIRTHDATE
else
BIRTHDATE=$1
fi

#Assigning the user values into variables: year, month and day
YR=${BIRTHDATE:0:4}
MTH=${BIRTHDATE:4:2}
DAY=${BIRTHDATE:6:2}

#Checking to see if the date entered is exactly 8 characters long
BIRTH_LEN=`expr length $BIRTHDATE = 8`
if [ $BIRTH_LEN = 0 ] ; then
echo "You entered `expr length $BIRTHDATE` characters, please enter your birthday in the form YYYYMMDD error 1"

#Checking to see if the date entered contains any non-numeric characters
#elif !(($BIRTHDATE -1)) 2> /dev/null ; then
elif echo $BIRTHDATE | grep  ^[0-9]*$ > /dev/null 2>&1 ; ! [ $? = 0 ] ; then
echo "Your entry contains non-numeric characters, please enter your birthday in the form YYYYMMDD error 2"

#Checking to see if the date entered is a future date
elif [ $BIRTHDATE -gt `date +"%Y%m%d"` ] ; then
echo "You entered $BIRTHDATE, which is a future date, please enter your birthdate in the form YYYYMMDD error 3"

#Checking to see if the date is invalid. Looking at months that are 31 days
elif [ $MTH -eq 1 ] || [ $MTH -eq 3 ] || [ $MTH -eq 5 ] || [ $MTH -eq 7 ] || [ $MTH -eq 8 ] || [ $MTH -eq 10 ] || [ $MTH -eq 12 ] && [ $DAY -gt 31 ] ; then
echo "You entered $BIRTHDATE, which is an invalid date. Please enter your birthdate in the form YYYYMMDD error 4"

#Checking to see if the date is invalid. Looking at months that are 30 days
elif [ $MTH -eq 4 ] || [ $MTH -eq 6 ] || [ $MTH -eq 9 ] || [ $MTH -eq 11 ] && [ $DAY -gt 30 ] ; then
echo "You entered $BIRTHDATE, which is an invalid date. Please enter your birthdate in the form YYYYMMDD error 5"

#Checking to see if the date is invalid. Looking at February and leap years.
elif [ $MTH -eq 2 ] && [ $((YR%400)) -eq 0 ] && [ $DAY -gt 29 ] || \
[ $((YR%4)) -eq 0 ] && [ $((YR%100)) != 0 ] && [ $DAY -gt 29 ] || \
[ $MTH -eq 2 ] && [ $DAY -gt 28 ] ; then
echo "You entered $BIRTHDATE, which is an invalid date. Please enter your birthdate in the form YYYYMMDD error 6"

elif [ $YR -gt `date +"%Y" -d "-12 years"` ] ; then
echo -e "\n\n I don't think so, my child!\n\n"

else
echo -e "\n\nIt works!\n\n"
fi
 
Old 06-09-2006, 11:28 AM   #8
MensaWater
LQ Guru
 
Registered: May 2005
Location: Atlanta Georgia USA
Distribution: Redhat (RHEL), CentOS, Fedora, CoreOS, Debian, FreeBSD, HP-UX, Solaris, SCO
Posts: 7,075
Blog Entries: 14

Rep: Reputation: 1251Reputation: 1251Reputation: 1251Reputation: 1251Reputation: 1251Reputation: 1251Reputation: 1251Reputation: 1251Reputation: 1251
Lightbulb

Quote:
Originally Posted by Blackout_08
I can't use the exit command. Its a restriction i have
Its not a restriction in shells so it makes me suspect you're asking us to do your homework for you.

A suggestion - use indenting for such nested ifs. That way you'll know which elif, else and fi go with which "if". You may simply be getting to a fi before or after you really intend to.

Code:
if  a
then if x
     then y
     else z
     fi
elif b
else c
fi
Makes it a lot easier to figure out y z and the first fi relate to the second if rather than the first if.

And of course you didn't comment on the suggestion to use case instead of if.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
bash ctrl+a not working! SteveGodfrey Linux - General 3 09-10-2004 08:48 AM
bash script not working :'( aesahaettr Linux - Software 5 05-12-2004 02:08 AM
bash scripting question - elif ?? xscousr Programming 2 08-12-2003 10:56 AM
bash and kde not working macshark Linux - Newbie 1 12-23-2002 02:12 PM
elif??????????? embsupafly Programming 1 11-27-2002 04:48 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 11:41 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration