fritz@polecat.caltech.edu (Fritz Nordby) (06/01/87)
I don't know if this has been noticed before, but there is a severe problem with make and Bourne shell scripts. If the IFS environment variable is set when make is invoked, then make resets IFS to an empty string. This almost guarantees that Bourne shell scripts will die horribly. To repeat, create an empty directory, cd there, and do: % /bin/sh $ cat >foo <<FOO echo \$# set "\$@" echo \$# FOO $ chmod +x foo $ cat >makefile <<FOO x: y foo 1 2 3 FOO $ >y $ foo 1 2 3 3 3 $ IFS=' ' $ # that's IFS='<space><tab><newline>' $ export IFS $ foo 1 2 3 3 3 $ make foo 1 2 3 3 1 $ ^D % The final "1" output by foo is the error. The problem is that the set "$@" in foo is being expanded into set "1" "2" "3" which, since IFS is empty (and therefore there are no field seperators), is interpreted as set "1 2 3" -- i.e., there is just one argument to set. Needless to say, this causes some problems. For example, suppose /bin/cc is a shell script which invokes the compiler after adding some flags to the comand line: #!/bin/sh exec /lib/cc -foo -bar "$@" If IFS is set when make is invoked, and if make invokes cc, then /lib/cc will be invoked with argc==2, as if it had been invoked by exec /lib/cc "-foo -bar $*" Fritz Nordby. fritz@vlsi.caltech.edu cit-vax!fritz
xsimon@its63b.UUCP (06/03/87)
In article <2888@cit-vax.Caltech.Edu> fritz@polecat.Caltech.EDU (Fritz Nordby) writes: >I don't know if this has been noticed before, but there is a severe problem >with make and Bourne shell scripts. If the IFS environment variable is set >when make is invoked, then make resets IFS to an empty string. This almost >guarantees that Bourne shell scripts will die horribly. It's not that it resets it to an empty string explicitly - it's a side-effect of the way that Make sets up make-variables from the environment list. What it does is it parses each environ entry for <name>=<value>, and then just simulates an assignment (such as <name> = <value> inside a Makefile). Of course, it strips out any "whitespace" between the <name> and the <value> - which is very embarassing for variables such as IFS in which the whitespace is an important part of the <value>. The same problem occurs for ANY variable which has an initial whitespace component - the whitespace will get stripped off by Make. -- ---------------------------------- | Simon Brown | UUCP: seismo!mcvax!ukc!{its63b,cstvax}!simon | Department of Computer Science | JANET: simon@uk.ac.ed.{its63b,cstvax} | University of Edinburgh, | ARPA: simon%{its63b,cstvax}.ed.ac.uk ... | Scotland, UK. | @cs.ucl.ac.uk ---------------------------------- "Life's like that, you know"
gwyn@brl-smoke.UUCP (06/04/87)
In article <2888@cit-vax.Caltech.Edu>, fritz@polecat.caltech.edu (Fritz Nordby) writes: > ... If the IFS environment variable is set > when make is invoked, then make resets IFS to an empty string. That isn't quite what's happening. Environment strings are handed to the YACC-based parser inside "make", with the idea that they'll be treated just like a "NAME=value" definition within a makefile. Eventually it is the parsed-and-assigned-to-"make"-variables values that get put back in the environment when augmented "make" forks a shell. What is happening here is that the parser cannot handle environment variables containing funny stuff like newlines. I don't know how to fix this other than to rip all the environment fooey out of "make". Better to not screw around with IFS. I think every shell should set IFS to defaults when it starts up rather than trusting the IFS that may be in the environment. That would also avoid your problem.