Shell basics

Hi All,

I have a basic question in Scripting.

Can anyone tell me what is the difference b/w the two syntax :

if (( $lines = 0 ));

and

if [ $lines -eq 0 ];

when do we use the square brackets & when to use the paranthesis.

Thanks,
Pradeep

$(( )) is added later and is used for mathematics foo=$(( 1+1+1+1+1 ))

[ $foo -eq 0 ] is calling test with arguments $foo -eq 0

if [ $lines -eq 0 ]

This came first. With the old bourne shell it is all you have. So it works everywhere. But it is not what it seems to be. The if statement runs a command and tests to see if it worked. So you can do stuff like:
if mkdir tmp ; then echo mkdir worked ; fi
mkdir is just a command and tmp is parameter to mkdir. There is a command called [ and like many commands it takes parameters. It checks its last parameter and gets mad unless it is ]. If the last parameter is a ], it looks at everything else and tries to determine what you are trying to test. If you do:
lines=""
if [ $lines -eq 0 ]
you will have a problem. All that the [ command will see is the -eq and the 0 so it will complain. Because of these concerns, Dave Korn invented another syntax. Now you can do:
if [[ $lines = 0 ]]
and it won't get mixed up as easily. Bash has picked this up from ksh and it is a better choice than the single [ most of the time. The idea is that [ might disappear eventually, but I tend to doubt that it will. Still, the official word is that [ is present in ksh to support older scripts and you should switch to [[.

But you asked about "if (($lines = 0 ))". That precise syntax is a terrible mistake and you probably should never use it. First, ksh has built-in arithmetic and you can do stuff like:
((k=7+1)) ; echo $k
and get 8. The ((expression)) syntax is just a command to do arithmetic. This command has an exit code. If the expression is non-zero, the command succeeds. But if the expression is zero, the command fails. So you can test the result of an expression. I often do stuff like:
if ((lines == 0 ))
which tests if lines is equal to 0. With (($lines = 0)), assuming that lines contained the name of another variable, it might almost work:
lines=xyz
if (($lines = 0))
$lines would be replaced by xyz, so the shell would see ((xyz = 0)). xyz would set to 0. ((xyz = 0)) would always fail so the if statement would never be true. You never need to use a $ sign inside ((expression)). This is ok:
((lines=lines+1))
The arithmetic statement will know that lines is a variable and will look up the value. Bash has also picked up arithmetic from ksh.

I didnt get a clearer picture about this before. Thanks Perderabo. May be this could be put in the FAQ section?!!