Register
It is currently Wed Sep 03, 2014 1:02 am

a Simple Bash IF Statement is killing me


All times are UTC - 6 hours


Post new topic Reply to topic  [ 9 posts ] 
Author Message
 PostPosted: Sat Jun 04, 2005 3:53 am   

Joined: Sat Jun 04, 2005 3:16 am
Posts: 16
Location: That Lunar Colony That Everybody Denies the Existance of.
Help. I can't understand why this doesn't work:

ok in a script I eventually generate a string variable called tomorrow with contents something like: (the quotes are containers of the string on this page, but not part of the string itself)

"02:00-04:00 PartSys Reboots.

Wally Vacation

Medco's internal ticket number - CHG2349."

So the code goes along until:

if [ tomorrow ];
then
echo "<br>etc more text and html"
echo $tomorrow
echo "<br>more useless text and html"
fi


The idea is, if $tomorrow contains any text, print it out with some standard prettifiying html and other text. If its empty then skip the 3 echo statements between then and fi.

However I simply can't get it to work. I've tried every variation of brackets, parenthesis, semicolons and positioning of the "then" statement and using the test command with and without -n or -z, etc.

What happens is no matter what tomorrow is set to the then branch is executed. Or sometimes the mangled mess of [ { ( $( gt != , etc is so bad it generates and error.

*********************
This is driving me insane.
*********************

Finally I've gave up and am doing this ugly thing:

len=`echo ${#tomorrow}`
if [ $len != 0 ];
then
echo "<tr><th><h3>blah blah
echo $tomorrow
echo "</h3></td></tr>"
fi

This works but what I've been reading seems to make me think the first example or something very similar should work just fine, but it doesn't.

Its: GNU bash, version 2.05a.0(1)-release (i386-pc-linux-gnu) on debian 3.0 stable.

Is there something I out you can point me to to be able to really understand this, I can't find much to read that really helps my addled brain. Thanks.


Top
 Profile  
 PostPosted: Sat Jun 04, 2005 11:37 am   
Site Admin

Joined: Tue May 17, 2005 7:31 pm
Posts: 251
Location: Georgia
hey gregg...
let's do it this way...
since if is checking whether something is true or not... (i.e. exit status of 1 or 0)
then you want to compare if something is true (exit status 0)
and you want it to react with something equalling 0
so how about this
Code:
if [ ! ${#tomorrow} ]
then
          echo "<tr><th><h3>blah blah
          echo $tomorrow
          echo "</h3></td></tr>"
fi

that is saying
bash wrote:
if not 0
then
do something
fi

what is in the if statement will only work if the length of the tomorrow variable does not equal 0
if it does equal 0... you will have to supply something for the else
hope this helps you understand the if statement a little better :)


Top
 Profile  
 PostPosted: Sun Jun 05, 2005 4:06 am   

Joined: Sat Jun 04, 2005 3:16 am
Posts: 16
Location: That Lunar Colony That Everybody Denies the Existance of.
Reading the info page, I got the impression

If [ tomorrow ]
then
do-something
fi

without the ${} would evalue the same, or maybe I'd have to use "test -n tomorrow". I'm just not understanding the expression bracketing/curlybracketing which is hard to experiment with because the if statement has such a harsh positional syntax. As in is there a ; before the then, etc.

Its weird how IF statements seem so hard in bash, but in Pascal and C, you can read a couple of examples in the book and fully understand them in less than 15 minutes.

Did sh/bash exist before programmers really worked out how the IF statement should work and it was just sort of rammed into existing syntax?


Top
 Profile  
 PostPosted: Sun Jun 05, 2005 3:17 pm   
Site Admin

Joined: Tue May 17, 2005 7:31 pm
Posts: 251
Location: Georgia
the ${} helps to single it out
so you can do firstPartOfString${somestring}theRestOfTheString
without it misreading what the variable $somestring is.
just good practice to always do it

as far as the ;
that is needed only if you are entering more than one line on one line
hence
Code:
if [ $bob ]; then do something; fi

is the same as
Code:
if [ $bob ]
then
do something
fi

in your example
gregg451 wrote:
if [ tomorrow ]
then
do-something
fi

the largest problem with that is the lack of the $ before the name of the variable "tomorrow"
in bash programming...the only time you don't use the $ before the variable name is when you are assigning the variable
the above example will always come out true...
Code:
<- jb:/home/jbsnake/scripts -> if [ tomorrow ]; then echo true; fi
true
<- jb:/home/jbsnake/scripts ->

ok...you want a good example (hopefully you read my tutorials first ;) )
write this in a shell script

Code:
#!/bin/bash

bob="thisText"
bill=""

if [ bill ]
then
echo true
else
echo false
fi

if [ $bill ]
then
echo true
else
echo false
fi

if [ bob ]
then
echo true
else
echo false
fi

if [ $bob ]
then
echo true
else
echo false
fi

you should get the lines written back
bash wrote:
<- jb:/home/jbsnake/scripts -> ./testIf
true
false
true
true
<- jb:/home/jbsnake/scripts ->


i didn't use curly brackets so as not to confuse you...
curly brackets are really to contain the variable
since you seem to be familiar with C...you would know that trimming a word is tedious using that language...you basically have to step through the entire string array in order to accomplish what you want
however...bash makes that soooo easy
take a variable called greet
let's assign it to contain the string "hi there"
Code:
greet="hi there"

so if we were to do:
Code:
echo "$greet"

then we get:
hi there
spit back out
but let's say we wanted to personalize our greeting
we would want to say hi but not there
we would want to say something like "hi bob"
but why create a new variable?
why not just say:
Code:
echo "${greet:0:3}bob"

that is taking the same variable and starting at the first position (which is 0) and having a length of 3
so contained within the variable ${greet:0:3} is "hi "
the above would echo back "hi bob"
do you see how the containment works by using the curly brackets?
and the way to get a complete length of our variable is ${#greet}

it seems i have steered off the point a little (but the information i hope if valuable all the same :) )

the if statement is so "hard" in bash because of it's versatility
i know you probably think i'm a little coocoo because of how strict the spacing is along with the syntax, but it is extremely versatile
in some cases you don't even need the [] at all
let's say we wanted to test to see if a directory existed
Code:
if test -d /home/jbsnake/scripts
then
echo "it exists"
else
echo "doesn't exist"
fi

that would ofcourse echo "it exists" (can't live without it :) )
the brackets actually are there to help simplify the if statement
instead of having to type the word test
you can just type
Code:
if [ -d /home/jbsnake/scripts ]
then
echo "it exists"
else
echo "it doesn't exist"
fi

test was made so you can make it known that you are actually testing something
if you were to want to drop the [], you could
because test can handle it all for you without having to worry too much about spacing
test can be used for testing anything
here's some clips from the man page about test
man test wrote:
-z STRING
the length of STRING is zero

STRING1 = STRING2
the strings are equal

STRING1 != STRING2
the strings are not equal

INTEGER1 -eq INTEGER2
INTEGER1 is equal to INTEGER2

INTEGER1 -ge INTEGER2
INTEGER1 is greater than or equal to INTEGER2

INTEGER1 -gt INTEGER2
INTEGER1 is greater than INTEGER2

INTEGER1 -le INTEGER2
INTEGER1 is less than or equal to INTEGER2

INTEGER1 -lt INTEGER2
INTEGER1 is less than INTEGER2

INTEGER1 -ne INTEGER2
INTEGER1 is not equal to INTEGER2

-d FILE
FILE exists and is a directory

-e FILE
FILE exists

-f FILE
FILE exists and is a regular file

-g FILE
FILE exists and is set-group-ID

-h FILE
FILE exists and is a symbolic link (same as -L)

-r FILE
FILE exists and is readable

-w FILE
FILE exists and is writable

-x FILE
FILE exists and is executable


ok...i think that's enough for this post
hope this helps out a little
:)


Top
 Profile  
 PostPosted: Wed Jun 08, 2005 10:14 pm   

Joined: Sat Jun 04, 2005 3:16 am
Posts: 16
Location: That Lunar Colony That Everybody Denies the Existance of.
Thanks for the info, that helps to clear some things up. I didn't even enough about being able to pull parts of a string with the help of the curly brackets. That helped me fix a problem I posted in a different section. There may be a nicer way to do it, but it works. Thanks.

It didn't make any sense to me at the time, but I tried:

if [ $tomorrow ]

and

if test -n $tomorrow

but when using the $ I always got an error complaining about too many parameters or arguments.


Top
 Profile  
 PostPosted: Wed Jun 08, 2005 10:51 pm   
Site Admin

Joined: Tue May 17, 2005 7:31 pm
Posts: 251
Location: Georgia
first off....
if [[ $tomorrow ]]
doesn't really test anything
if test -n $tomorrow
doesn't either
if test $tomorrow
will return true if $tomorrow has a length
if test -n3 > $tomorrow
will return true if $tomorrow's length is less than or equal to 3
if you just want to see if $tomorrow has no length (empty variable)
if test -z $tomorrow
will return true if the length of $tomorrow is 0


Top
 Profile  
 PostPosted: Fri Nov 28, 2008 10:57 pm   

Joined: Fri Nov 28, 2008 10:32 pm
Posts: 3
Oh ye men of little faith ...

Always, but always quote your variables. Granted - it's not always neccessary but there are indeed many cases where it _must_ be used:
Code:
a="hello world"    # refer to it as "$a"
b="hello"             # refer to it as $b or "$b"
c=""                    # refer to it as "$c"



The correct test is:
Code:
if test -z "$tomorrow"   # or if you prefer:   if [ -z "$tomorrow" ]
then   # do something when 'tomorrow' is empty
else    # 'tomorrow' is non-empty
fi


This is the reason why you get complaints of too many parameters or arguments.

If indeed 'tomorrow' is empty, and you write:
if [ -z $tomorrow ]
then this has the exact same action as:
if [ -z ]
which will cause a 'missing argument' error message


Top
 Profile  
 PostPosted: Tue Dec 02, 2008 7:07 am   

Joined: Mon Nov 17, 2008 7:25 am
Posts: 221
loki wrote:
Oh ye men of little faith ...

Always, but always quote your variables. Granted - it's not always neccessary but there are indeed many cases where it _must_ be used:


I agree, always quote your string variables. And if you're not sure what your variable contains, quote it.
Only time you don't need to quote it is when you're working with integers. And this does not include floating point numbers (numbers with decimals).

And yes, the proper way is to use "if zero" syntax :) for test or in [ -z ].

if you want to loose 1 else you can write it like this:
Code:
if [ ! -z "$tomorrow" ]; then
   commmand ...
fi

This will reverse the -z effect and check if the condition isn't zero :)

Best regards
Fredrik Eriksson


Top
 Profile  
 PostPosted: Tue Dec 02, 2008 8:42 am   

Joined: Tue Dec 02, 2008 8:30 am
Posts: 6
Location: Bonny Scotland
alternatively this would work
Code:
if ! [ "$tomorrow" = "" ]; then
  command ...
fi


Top
 Profile  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 9 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: No registered users and 7 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Jump to:  
cron


BashScripts | Promote Your Page Too
Powered by phpBB © 2011 phpBB Group
© 2003 - 2011 USA LINUX USERS GROUP