[comp.unix.wizards] eval bug + prompt wars

rbj@icst-cmr.arpa (04/15/87)

   I've noticed a rather strange behavior in BSD 4.2-3 systems' eval command.
   If you put the following into a file called eval.bug:

     set noglob;
     setenv FOO '*';
     unset noglob;

   and then execute the command: 

     eval `cat eval.bug` 

   repeatedly, the command works *every other* time. When it fails, it
   gives the message "setenv: Too many arguments" because it expands the '*'. 

Your problem is context. It has always escaped me the *precise* 
order the expansion of history, alias, variable, backquoting, redirection,
command parsing and the like occur. The manual attempts an explanation,
and reading the sections gives a pretty good idea, but to some extent it
seems recursive. Please note I am *not* asking for that information.

   The commands:

     eval <eval.bug

Does nothing. Eval seems to look only at args, not stdin.

   and: 
     eval set noglob; setenv FOO '*'; unset noglob;

Here the semicolon seems to be seen and the set command acted upon before
the star is ever seen. Thus, csh's internals know not to expand it. In the
backquote case, the entire line is globbed before it is rescanned by eval,
whereupon the semis take on significance.

   work just fine. The strange behavior happens because, every other
   time, the command bombs out before eval'ing "unset noglob;", thus leaving
   noglob set *before* every other iteration.

Correct.

   Bleah, that was a horrible description, let me try another tack: the
   command works fine every time if you set noglob before executing it.

Bleah, that was a horrible explanation. `Set' is a metacommand, which
changes the context of the scanner, which may have already scanned
the command in question. You can't expect "set noglob foo=*" to work either.

After playing around a bit, I found:	eval "`cat eval.bug`"

   Is this a bug in the way `<cmd>` works, or is it a known "feature"? 

This looks like a good opportunity to flame the csh for all it's 
slipperiness and vaguery, but the whole notion of quoting and evaluating
is that kind of a problem. Consider LISP for example. I still get confused.

Add to that the fact that the flamers would be partially correct, and
that all the features aren't quite as orthogonal as they should be.

   It's particularly annoying because it's sometimes convenient to do:

     setenv TERMCAP `tset -SQ vt100`

   and, as we all know, the vt100 termcap entry has lots of nasty little
   "["s floating around in it.

Probably the best thing to do here is use an alias that sources a canned
file after set'ing term. I use: alias term 'set term=\!*;source ~/term'.
The file ~/term appears below, with `@'s substituted for escapes.
This is another therefore chapter in `prompt wars'. Reverse video!

switch  ($TERM)
case network:					# Telnet
case dialup:					# Modem
case unknown:
	set noglob
	eval `tset -I -s -m "dialup<=2400:?950" -m "network:?vt100-np"`
	breaksw
default:					# $TERM known
	set noglob
	eval `tset -I -s "$TERM"`
endsw
tset -Q "$TERM"					# SEQUENT BUG: -Q/-s
set term=$TERM
switch  ($TERM)
case tvi950-b:					# Televideo, bare
	set	prm =	 "@G<($HOST \!)@G0"
	goto	def
case *950*:					# Any, 950; use sts line
	set	prompt = "@G<($HOST \!)@G0"
	goto	stat
case vt100-s*:					# vt100 with sts line
	set	prompt = "@[4;7m($HOST \!)@[m "
stat:
	sh	$RBJ/term/ks			# Kill prv `sysline'
	setenv	SYS	`sysline -bDhij`
	alias	ks	'echo $cwd > ~/.who;kill -ALRM $SYS'
	alias	cd	'cd	\!* ; ks'
	breaksw
case vt100*:					# vt100/220
case sun:					# as in `Workstation'
	set	prm = "@[4;7m($HOST \!)@[m "
	goto	def
case dw3:					# DECwriter III
case *152[01]:					# Datamedia
case dumb:
case unknown:
default:					# The Other One
	set	prm = "($HOST \!) "
def:
	alias	cd	'cd	\!* ; set prompt="$cwd $prm"'
	breaksw
endsw
cd	.					# Indicate CWD


					   ../ray\..
    (trent@csvax.caltech.edu, rat@caltech.bitnet, ...seismo!cit-vax!trent)

(Root Boy) Jim "Just Say Yes" Cottrell	<rbj@icst-cmr.arpa>
Tex SEX!  The HOME of WHEELS!  The dripping of COFFEE!!  
Take me to Minnesota but don't EMBARRASS me!!