[net.unix-wizards] /bin/sh variable substitution

jdb@mordor.UUCP (John Bruner) (06/29/84)

I noticed recently that the (Bourne) shell's ${X=y} construction
does not have the behavior that I expected.  It appears that when
a variable is assigned a quoted value, for example:

	${XYZZY="plugh"}  <or>	${XYZZY='plugh'}

that every character of the quoted value is stored with the 0200
bit on.  Normally this has no visible effect because the shell
strips the eighth bit (along with  non-printable characters) after
variable substitution when it evaluates a command.  However, this
is not the case for "<<" I/O redirection: the variables are passed
unfiltered.  For instance, in the following case:

	cat > plover <<!EOF!
	${XYZZY="plugh"}
	!EOF!

the file "plover" will contain "\360\354\365\347\350\n"

I also observed this behavior with the ${X-y} construction.  The
0200 bits are not set if the string is unquoted: ${XYZZY=plugh}

I tried this on V7, 4.1BSD, 4.2BSD, and UniPlus+ (Sys 3), all
with the same results.

Has anyone seen (and hopefully fixed) this one before?
-- 
  John Bruner (S-1 Project, Lawrence Livermore National Laboratory)
  MILNET: jdb@mordor.ARPA [jdb@s1-c]	(415) 422-0758
  UUCP: ...!ucbvax!dual!mordor!jdb 	...!decvax!decwrl!mordor!jdb

gwyn@brl-vgr.ARPA (Doug Gwyn ) (06/30/84)

I tried your example using a UNIX System V Bourne shell.  The 0200
bits were not set.  I suppose that answers the question whether this
bug has been fixed.

dave@utcsrgv.UUCP (Dave Sherman) (07/01/84)

In article <4260@mordor.UUCP> jdb@mordor.UUCP (John Bruner) writes:
~| I noticed recently that the (Bourne) shell's ${X=y} construction
~| does not have the behavior that I expected.  It appears that when
~| a variable is assigned a quoted value, for example:
~| 
~| 	${XYZZY="plugh"}  <or>	${XYZZY='plugh'}
~| 
~| that every character of the quoted value is stored with the 0200
~| bit on.  Normally this has no visible effect because the shell
~| strips the eighth bit (along with  non-printable characters) after
~| variable substitution when it evaluates a command.  However, this
~| is not the case for "<<" I/O redirection: the variables are passed
~| unfiltered. 
~| 

Aha! That explains the strange behaviour I got on one system, where
I was trying to use "cu" across a hardwired line, requiring a null
first argument (nothing to dial).

I can type to the shell:
	cu "" -s 2400 -l /dev/whatever

but when I put CU='cu "" -s 2400 -l /dev/whatever' in my .profile,
I couldn't get $CU to work, and the error meesage from cu was one
I couldn't reproduce by typing at the screen. No amount of fiddling
with different combinations of quoting chars helped. Musta been those
eighth bits acting up. Yep, it's a bug.

Dave Sherman
Toronto
-- 
 {allegra,cornell,decvax,ihnp4,linus,utzoo}!utcsrgv!dave
or
 David_Sherman%Wayne-MTS%UMich-MTS.Mailnet@MIT-Multics.ARPA

joec@u1100a.UUCP (Joe Carfagno) (07/02/84)

{eat me}
We solved a similar problem with the 0200 bit set.  This fix may solve
this problem, maybe not.  Don't quote me on the line numbers either.
The file is /usr/src/cmd/sh/macro.c
 
Line 132-133	THEN	IF n
			THEN	assign( n, argp ) ;
becomes
		THEN	IF n
			THEN	trip( argp ) ;
				assign( n, argp ) ;
This strips off the 0200
before assigning the variable, or something like that.

henry@utzoo.UUCP (Henry Spencer) (07/04/84)

This problem seems to be fixed in the System V shell.  We run V7,
but with the System V shell -- it's a good deal less buggy than the
V7 one, and it wasn't hard to make it run under V7.
-- 
				Henry Spencer @ U of Toronto Zoology
				{allegra,ihnp4,linus,decvax}!utzoo!henry