From: mflll@uxa.ecn.bgu.edu (Dr. Laurence Leff)
Subject: Much Ado about Nothing: white space and sh and csh
Keywords:  csh sh test expr
Organization: Educational Computing Network
Date: Tue, 7 Apr 1992 17:59:11 GMT

I was fooling around with the shells.

I seem to be confused as to the reason for the location of spaces
in one case with the "sh"

The following program generates the syntax error "u: not found"

:
: comment
u = 3
echo u $u
t=`expr $u + 1`
echo t $t

I try the same program -- only removing the spaces around the equal
sign in u = 3.

And it works.

:
: comment
u=3
echo u $u
t=`expr $u + 1`
echo t $t

sh seems to not want spaces around  it's assignment operator.  It complains
quite violently, when they are included.  I have the sh(1) manual in
front of me.  There is no insignt provided as to the reason for this
pickiness.

On a related note, recall that each operator in the expr command is a
separate argument.    I found this documented in expr(1).

Thus, one needs spaces around the expression.  The following statements
illustrate z:=u+u.

$ u=3
$ z=`expr $u + $u`
$ echo $z
6
$ 

If one forgets the spaces, one gets the following bizarre behavior.


$ 
z=`expr $u+$u`
$ $ echo $z
3+3
$ 

On some other notes, in csh, the assignment operator is 
of the form "@ space assignment statement"

It seems that one can have the left hand side of the equation, the equal
sign, and the right hand side of the equal sign separated by spaces at the
option of the users.

The following is accepted quite happily by the csh:

#
@ x=4
@ y=2
@ x=$y
echo $x
  
As is this,

#
@ x = 4
@ y = 2
@ x = $y
echo $x
	
However, when I remove the space from after the "@", the csh is quite
unhappy.

#
@x = 4
@y = 2
@x = $y
echo $x

It keeps complaining that "@x: Command not found"  and "@y: Command not found"

It really isn't too clear from csh(1) that @ would require this space.  It
does say, "Spaces are, however, mandatory in spearating components of expr which would otherwise be single words."  So that probably explains why the spaces are
optional around the equal signs.

Now, let's look at the while loop in csh.  The following makes csh very
happy and it cheerfully prints out the numbers from 1 to 3.

#
@ i = 1

while ( $i <= 3 ) 
  echo $i
  @ i = $i + 1
end
 
This makes csh violently ill.  It complains, 
"while: Expression syntax."

#
@ i = 1

while ( $i<=3 ) 
  echo $i
  @ i = $i + 1
end

The only difference is the spaces around the relational operator "<="
Could csh be looking for the variable named "i<=3"?

Along the same lines, here the system is having trouble with the
statement to increment i.  I suspect that it is looking for a variable
called "i+1"



#
@ i = 1

while ( $i <= 3 ) 
  echo $i
  @ i = $i+1
end

this time, the csh complains:

@: Badly formed number

And, now, we try while's in sh.
The syntax is listed in a single line in the man page for  sh(1) like so:
while list [do list] done

However, we will see that various illogical carriage returns are required
to make sh happy.

The following makes sh quite happy and it cheerfully gives me the numbers
from one to three:

i=1
while test $i -le 3
do
   echo $i
   i=`expr $i + 1`
done   

This will make sh quite happy as well.  Notice I put the "echo" on the
same line with the "do"

i=1
while test $i -le 3
do echo $i
   i=`expr $i + 1`
done   

but should I put the "done" on the same line as the last statement,
all hell breaks loose:

i=1
while test $i -le 3
do
echo $i
   i=`expr $i + 1` done   

But, I can propitiate the god with an offering of a semicolon:

i=1
while test $i -le 3
do
echo $i
   i=`expr $i + 1`; done    

The code below confuses "sh" as well.  Presumably, it can't tell that "do" is a keyword and passes it to "test"

i=1
while test $i -le 3  do
echo $i
   i=`expr $i + 1`; done   

Generates

/tmp/doy: syntax error at line 4: `done' unexpected

And again,a semicolon will propitiate the gods:

i=1
while test $i -le 3 ; do
echo $i
   i=`expr $i + 1`; done   

I hope you all found this discussion of 
"space" and "return" sensitivity as entertaining to read as it was
to write.
I haven't seen any other language as bizarre as this.