[comp.unix.questions] Is this a bug in sh?

paul@moncam.co.uk (Paul Hudson) (07/04/89)

Am I just showing my ignorance of sh?
Consider the two (executable) shell scripts..

script1 is		and  	script2 is

echo $0				echo $0
name=`basename $0`		name= `basename $0`
				     ^
			Note the space here.

executing script1 prints "script1" as you would expect.  Executing
script2 prints "script2" "script2" ...... and spawns shells at an
enormous rate.

This is sunos4.0 on a sun3/50.

Go on, tell me I haven't RTFM .... ;-) Then tell me why it's this way.


--
Paul Hudson	 MAIL: Monotype ADG, Science Park, Cambridge, CB4 4FQ, UK.
		PHONE: +44 (223) 420018	  EMAIL: paul@moncam.co.uk,
	;"	  FAX: +44 (223) 420911		 ...!ukc!acorn!moncam!paul
 `"";";"        "/dev/null full: please empty the bit bucket"

mveao@cbnews.ATT.COM (eric.a.olson) (07/05/89)

In article <PAUL.89Jul4155856@marvin.moncam.co.uk> paul@moncam.co.uk (Paul Hudson) writes:
>
>Consider the two (executable) shell scripts..
>script1 is		and  	script2 is
> echo $0			echo $0
> name=`basename $0`		name= `basename $0`
>Go on, tell me I haven't RTFM .... ;-) Then tell me why it's this way.

    They both evaluate the basename of their shell -- script1 and script2,
    respectively.  The first assigns this to the variable $name;
    the second, however runs it as yet another command,
    in an environment where the variable $name is set to null.
    This causes recursion and the spawned shells you mentioned.


fodder
fodder
fodder

frank@zen.co.uk (Frank Wales) (07/05/89)

[I tried mailing, but it bounced.]

In article <PAUL.89Jul4155856@marvin.moncam.co.uk> paul@moncam.co.uk write:
>Consider the two (executable) shell scripts..
>
>script1 is		and  	script2 is
>
>echo $0				echo $0
>name=`basename $0`		name= `basename $0`
>				     ^
>			Note the space here.
>
>executing script1 prints "script1" as you would expect.  Executing
>script2 prints "script2" "script2" ...... and spawns shells at an
>enormous rate.

Valid shell construct number one;

Assignments to shell variables (a.k.a. keyword parameters) have the syntax:

	<varname>=<expression>

note...no spaces following the '='.  If <expression> is missing,
then <varname> is set to the null string.

Valid shell construct number two:

Execution of a command with a shell variable set to a particular
value *in the environment of that command only*:

	<varname>=<expression> <command string>

If <expression> is missing, <varname> is set to the null string while
<command string> is executed.  <command string> can be any shell expression
which results in a non-null string for subsequent execution.

Hence, in the example you give, the line:
	
	name= `basename $0`

sets name to the null string, evaluates the backquoted expression
(which results in the basename of the script), then executes the
script itself with name set to null.  This leads to unending
recursion of the script which contains it.

Today's complex technical question: based on this, decide what you
think the command line:

	binglebongle=Fred echo $binglebongle

will print, then try it and see what happens.  At this point, read the
manual.  :-)
--
Frank Wales, Systems Manager,        [frank@zen.co.uk<->mcvax!zen.co.uk!frank]
Zengrange Ltd., Greenfield Rd., Leeds, ENGLAND, LS9 8DB. (+44) 532 489048 x217 

terryl@tekcrl.LABS.TEK.COM (07/06/89)

In article <PAUL.89Jul4155856@marvin.moncam.co.uk> paul@moncam.co.uk (Paul Hudson) writes:
>
>Am I just showing my ignorance of sh?
>Consider the two (executable) shell scripts..
>
>script1 is		and  	script2 is
>
>echo $0				echo $0
>name=`basename $0`		name= `basename $0`
>				     ^
>			Note the space here.
>
>executing script1 prints "script1" as you would expect.  Executing
>script2 prints "script2" "script2" ...... and spawns shells at an
>enormous rate.
>
>This is sunos4.0 on a sun3/50.
>
>Go on, tell me I haven't RTFM .... ;-) Then tell me why it's this way.


     HOK, I'll tell ya "You haven't RTFM", but unfortunately, for this example
you have to read between the lines in TFM. What is happening in script2 is you
are assigning a null string to the variable name (by virtue of what you noted
"Note the space here."); in sh it is possible to have a command line of the
form:

	<variable-name>=<value-to-bet-set> <real-command-line>

      What this does is to put whatever <variable-name> is into the environment
variables, but only for the execution of <real-command-line>. So in your example
above, in script2 you are assigning the null string to the variable name, and
then putting the variable name into the environment temporarily for the running
of the command `basename $0` (which is script2, in your case). That's why
script2 keeps printing out "script2" "script2" and spawns shells at an enormous
rate.......


Help
Stamp
Out
Fascist
News
Software
!!!!
!!!!

pcf@galadriel.UUCP (Pete French) (07/06/89)

From article <PAUL.89Jul4155856@marvin.moncam.co.uk>, by paul@moncam.co.uk (Paul Hudson):
> 
> script1 is		and  	script2 is
> 
> echo $0				echo $0
> name=`basename $0`		name= `basename $0`
> 				     ^
> 			Note the space here.
> 
> executing script1 prints "script1" as you would expect.  Executing
> script2 prints "script2" "script2" ...... and spawns shells at an
> enormous rate.
> 
> This is sunos4.0 on a sun3/50.

This took some playing to figure out but....

Try this :

	$ name=abc date
	Thu Jul  6 13:36:38 WET DST 1989
	$ echo $name
	abc

The shell will do the assignment and then run the next command on the line
for some unexplained reason. What you have is

	name= `basename $0`

Which will be expanded (correctly) to

	name= script2

The shell will now assign a blank to name and run script2 - thus re-running
the same script. This is what is causing the multiple shells.

Why the shell executes a command on the same line as an assignment is beyond
me, however. You normally need semicolons to separate commands on the same
line in shell. It sems to be acting as if it was...

	$ name=abc; date

-Pete French.

gp@ist.CO.UK (GP Saxena) (07/07/89)

In article <PAUL.89Jul4155856@marvin.moncam.co.uk>, paul@moncam.co.uk (Paul Hudson) writes:
> Consider the two (executable) shell scripts..
> 
> script1 is		and  	script2 is
> 
> echo $0				echo $0
> name=`basename $0`		name= `basename $0`
> 				     ^
> 			Note the space here.
> 
> executing script1 prints "script1" as you would expect.  Executing
> script2 prints "script2" "script2" ...... and spawns shells at an
> enormous rate.
> 
This is because in script2, the shell treats the line
	name= `basename $0` 
as two separate actions viz.,

1. the parameter "name" is set to null.
2. the "simple command" (RTFM :-) ) `basename $0` is executed.

What happens in your case is that script2 gets executed within
script2 as a result of (2) above, and this happens recursively.
BTW, this will happen only if script2 is an executable shell
script!
> This is sunos4.0 on a sun3/50.
> 
> Go on, tell me I haven't RTFM .... ;-) Then tell me why it's this way.
> 
I tried this on other BSD systems, where too the same thing happens.
I do not think its a bug  though its a bit disconcerting when such a 
thing happens.

gp saxena

Disclaimer: I do not make any claims.

gwyn@smoke.BRL.MIL (Doug Gwyn) (07/07/89)

In article <PAUL.89Jul4155856@marvin.moncam.co.uk> paul@moncam.co.uk (Paul Hudson) writes:
>script1 is		and  	script2 is
>echo $0				echo $0
>name=`basename $0`		name= `basename $0`
>				     ^
>			Note the space here.

The space separates "words", so in script2 you're running a command
that is obtained as the output from the `` quoted command, prefixed
by a word that sets the environment variable "name" to an empty
string just for that one command.

It's not a bug; it's the way the shell is documented as working.
Change some other syntax and you'll get yet other variations in
behavior.

gwc@root.co.uk (Geoff Clare) (07/07/89)

In article <1634@zen.co.uk> frank@zen.co.uk (Frank Wales) writes:

>Today's complex technical question: based on this, decide what you
>think the command line:

>	binglebongle=Fred echo $binglebongle

>will print, then try it and see what happens.  At this point, read the
>manual.  :-)

Then try

	binglebongle=Fred echo "$binglebongle"

and really blow your mind.
-- 

Geoff Clare    UniSoft Limited, Saunderson House, Hayne Street, London EC1A 9HH
gwc@root.co.uk   ...!mcvax!ukc!root44!gwc   +44-1-315-6600  FAX: +44-1-315-6622