[net.unix] Help! Csh is eating my brain....

flory@zaphod.UUCP (Trevor Flory) (10/16/85)

Hello All;
	I'm trying to debug a csh script written by someone who
	knew what he was doing I'm sure.  Below is a fragment of
	the script which I find rather difficult to understand:
		...
		alias readandset 'echo -n \!:1 ; set \!:2 = $< ' 
		...
		readandset "Choice? " chvar
		...
		if("$chvar" == "quit") ....

	In particular I'd like to know what \!:1 or \!:2 means/does.

	Please note that I know the basics of csh but I'm no whiz so
	a full, step-by-step parse of how the above fragment is
	interpreted would not be out of order.  Thanks very much for
	your help.  Post or e-mail as you see fit.

-- 
Trevor K. Flory           UUCP: ...!ihnp4{!alberta}!sask!zaphod!flory
Develcon Electronics Ltd.             Saskatoon, Saskatchewan, CANADA

"... the play is the tragedy, `Man',
	And its hero the Conqueror Worm."
			Poe, c.1838

flory@zaphod.UUCP (Trevor Flory) (10/17/85)

In article <366@zaphod.UUCP> flory@zaphod.UUCP (that's me) writes:
>Hello All;
>	I'm trying to debug a csh script ....


Thanks to all who answered my Csh question.  Also thanks to all who
scorched my buns off with RTFM flames.
-- 
Trevor K. Flory           UUCP: ...!ihnp4{!alberta}!sask!zaphod!flory
Develcon Electronics Ltd.             Saskatoon, Saskatchewan, CANADA

"... the play is the tragedy, `Man',
	And its hero the Conqueror Worm."
			Poe, c.1838

pdg@ihdev.UUCP (P. D. Guthrie) (10/18/85)

In article <366@zaphod.UUCP> flory@zaphod.UUCP (Trevor Flory) writes:
>Hello All;
>	I'm trying to debug a csh script written by someone who
>	knew what he was doing I'm sure.  Below is a fragment of
>	the script which I find rather difficult to understand:
>		...
>		alias readandset 'echo -n \!:1 ; set \!:2 = $< ' 
>		...
>		readandset "Choice? " chvar
>		...
>		if("$chvar" == "quit") ....
>
>	In particular I'd like to know what \!:1 or \!:2 means/does.
>

This notation simply replaces itself with the corresponding arguments in
the original line, so it echos the first argument, and sets  the  second
one to a line from stdin.  Why doesn't ksh have something like  this?  I
hate having to use fc and mess around with its output - and that's soooo
inefficient! 

					Paul Guthrie

avolio@decuac.UUCP (Frederick M. Avolio) (10/19/85)

In article <366@zaphod.UUCP>, flory@zaphod.UUCP (Trevor Flory) writes:
> Hello All;
> 	I'm trying to debug a csh script written by someone who
> 	knew what he was doing I'm sure.  Below is a fragment of
> 	the script which I find rather difficult to understand:
> 		...
> 		alias readandset 'echo -n \!:1 ; set \!:2 = $< ' 
> 		...
> 		readandset "Choice? " chvar
> 		...
> 		if("$chvar" == "quit") ....
> 
> 	In particular I'd like to know what \!:1 or \!:2 means/does.

If you look at a command line, the first word is in position 0, the
next in position 1, and so on.  !:n (where n is a non-negative number)
the csh replaces the string with the word in the nth position from the
previous command.  (!:1 is the first word.  !22:3 is the 3rd word from
command #22 in the history and so on....)

Example --

% ls -ld t*
drwx--x--x 16 avolio       1024 Oct 17 15:23 text
-rw-r--r--  1 avolio          0 Oct 19 10:10 todo

% ls !:2
ls t*
todo

text:

cust.support	  decnet.info	    decuac	      kermit
mail		  paths		    products	      qpr
training	  uac		    uig		      ultrix11
ultrix32	  venix

-----

% echo a b c
a b c

% echo !:3
echo c
c

%


And so on.....

Fred.

itkin@luke.UUCP (Steven List) (10/20/85)

In article <366@zaphod.UUCP> you write:
>		alias readandset 'echo -n \!:1 ; set \!:2 = $< ' 
>		...
>		readandset "Choice? " chvar
>		...
>		if("$chvar" == "quit") ....
>
>	In particular I'd like to know what \!:1 or \!:2 means/does.

Aliases use current line history replacement.  \!:n means "replace
with word n of the current command line", where 0 is the first word (usually
the command itself).  If readandset were to be written as a Bourne shell
script, it would be as follows:

	prompt=$1
	echo "$1\c" < /dev/tty > /dev/tty
	read X
	echo X

and used as
	
	chvar=`readandset "Choice? "`

thus storing the user's input into variable chvar.  The use of "$<" in
the alias is the equivalent of "read chvar" in Bourne shell or the
alternate "set chvar = `line`" in C shell (ours does not support $<).

Thus, readandset can be define is pseudocode as

	print the second word of this command as a prompt without a
		following newline
	store the response typed in in the variable named as the second
		argument (word 2, third object)

The use of \!:n, where n can be any number, * (for all), or $ (for last),
is a very powerful means of defining macros in the C shell.  I use them
all over the place very effectively (also refer to various means of 
implementing popd, pushd directory change macros).
-- 
***
*  Steven List @ Benetics Corporation, Mt. View, CA
*  Just part of the stock at "Uncle Bene's Farm"
*  {cdp,greipa,idi,oliveb,plx,sun,tolerant}!bene!luke!itkin
***

tweten@AMES-NAS.ARPA (10/24/85)

From: pdg@ihdev.UUCP (P. D. Guthrie)

	>		alias readandset 'echo -n \!:1 ; set \!:2 = $< ' 

	Why doesn't ksh have something like  this?  I hate having to use
	fc and mess around with its output - and that's soooo inefficient!

I'm not a ksher, so I can't answer directly, but System V.2 sh has just the
thing, shell functions:

	readandset () { echo "$1\c"; read $2; }

To my eye, at least, it even looks better!