[net.unix] New uses for csh

gam@proper.UUCP (Gordon Moffett) (06/24/84)

It was begining to frustrate me that the csh ``alias'' command accepted
only one-line definitions; it is impossible to have an alias that uses
``if-then-else''.

My solution to this problem was using a combination of ``source''
and ``alias'' allow possibly lengthy alias-type commands using more
complex csh constructions.

This is particularly applicable in the following examples.  The UniSoft
port I am using does not support the ``pushd'' and ``popd'' commands
of csh, so I have implimented them thus:

[in my .cshrc]:
	alias	popd	'set argv = (\!*) ; source ~/csh/popd'
	alias	pushd	'set argv = (\!*) ; source ~/csh/pushd'

[~/csh/popd]:
	if (! $?_dirstack || $#_dirstack < 1) then
		echo "popd: Directory stack empty."
	else
		chdir $_dirstack[1]
		echo $_dirstack
		shift _dirstack
	endif

[~/csh/pushd]:
	if ($#argv != 1) then
		echo "pushd: Arg count."
	else
		if (! $?_dirstack) set $_dirstack = ()
		set _dirstack = (`pwd` $_dirstack)
		chdir $argv
		echo $argv $_dirstack
	endif

The advantages to this method are:
	o  More sophisticated (multi-line) csh constructs are allowed
	o  Operates on the current shell (qv, chdir)
	o  No overhead for reading .cshrc (as with an executable script)

The disadvantages are:
	o  Argv probably should be saved somewhere and restored
	o  No ``exit'' from ``if'' statements (other than -- ech --
	   ``goto'')
	o  Requires a file access

[ These scripts were derived from someone else's implimentation of
  pushd/popd for csh's lacking them; I don't recall who that is,
  but thank you anyway ]

[ Also do not use this as launch-point for another csh vs sh argument
  as it is not my intention to start one -- I shouldn't have to say
  this but I've been on the net for a while ... ]

Comments and discussion are encouraged.
-- 

Gordon A. Moffett

{ hplabs!nsc, decvax!sun!amd, ihnp4!dual } !proper!gam

mats@dual.UUCP (Mats Wichmann) (06/26/84)

RE: Gordon's neato implementation of pushd/popd for csh's that don't have
them....

>> [in my .cshrc]:
>>	alias	popd	'set argv = (\!*) ; source ~/csh/popd'
>>	alias	pushd	'set argv = (\!*) ; source ~/csh/pushd'

>> [~/csh/popd]:
>> 	if (! $?_dirstack || $#_dirstack < 1) then
>> 		echo "popd: Directory stack empty."
>> 	else
>> 		chdir $_dirstack[1]
>> 		echo $_dirstack
>> 		shift _dirstack
>> 	endif

>> [~/csh/pushd]:
>> 	if ($#argv != 1) then
>> 		echo "pushd: Arg count."
>> 	else
>> 		if (! $?_dirstack) set $_dirstack = ()
>> 		set _dirstack = (`pwd` $_dirstack)
>>  		chdir $argv
>> 		echo $argv $_dirstack
>> 	endif

I am not trying to criticise the intent of the article, which was to show
a method for fudging more complex alias commands. However, the specific
example used can be done more quickly, although it is not as complete an
emulation...

Try this (all in your .cshrc)

	if (! $?_d ) set _d = ()
	alias pushd	set _d = \(\`pwd\` \$_d\) \; cd \!\*
	alias popd	cd \$_d\[1\] \; echo \$_d\[1\] : \; shift _d

Avoids opening an extra file each time for the source, although it has a
less elegant error recovery...I use it quite a bit when jumping around
the system. 

	Mats

janney@unm-cvax.UUCP (06/30/84)

Re: using an alias to source a longer file

This can also be used to get which(1) to provide more up-to-date
information about your aliases: 

	alias which 'set argv=(\!*); source /usr/ucb/which; unset noglob'

Of course, it does zap argv, which might be a problem sometimes.

Jim Janney
{{convex,ucbvax,gatech}!unmvax, {purdue,lbl-csam,cmcl2}!lanl-a}!unm-cvax!janney

lamarche@micomvax.UUCP (07/18/84)

Header