A csh question ...

Lloyd Zusman ljz at fxgrp.UUCP
Sun May 22 10:03:50 AEST 1988


In article <3990 at csli.STANFORD.EDU> gandalf at csli.stanford.edu (Juergen Wagner) writes:
  In article <636 at fxgrp.UUCP> ljz%fx.com at ames.arc.nasa.gov (Lloyd Zusman) writes:
  >Can anyone explain why .login gets sourced *after* .cshrc?  ...
  
  I don't see why you would like to read .login first. Basically, .cshrc has
  the job of setting up things you'd like to have in *every* csh. Typically,
  you will have a unconditional section, and a section depending on the value
  of $?prompt. Everything else should go into .login.
  
Perhaps I didn't make myself clear.  For those of you who didn't
understand my question, let me try again, this time giving a bit more
detail ...

The C shell has, among other things, local shell variables (assigned
via the 'set' command) and environment variables (assigned via
'setenv').  The environment variables get inherited by children, while
the shell variables don't.  The .cshrc file gets sourced every time
csh is invoked (unless it's invoked with the -f option or it is a
shell script whose first line is "#!/bin/csh -f"), while .login gets
invoked only when I start up, *after* the initial invocation of .cshrc.

Since environment variables are automatically inherited by children, I
tend to use them to hold information that I may wish to know about in
all my subshells.  For example, if I do a

    setenv HOSTNAME "`hostname`"

in my login shell, all subshells will inherit this value.  On the
other hand, if I do a

    set HOSTNAME = "`hostname`"

I would have to repeat this command every time I enter a subshell, if
the value of HOSTNAME is important to me.  In the former case, it would
be logical to put the 'setenv ...' into my .login, and in the latter case,
the 'set ...' should be in .cshrc.

I tend to use very few 'set' variables, because I wish to avoid the
overhead of sourcing a .cshrc with lots of commands.  I almost always
write my csh scripts with the first line set to "#!/bin/csh -f" so that
they will start up quickly.  For these two reasons, among others, I
tend to use lots of environment variables.

Now, I also set aliases, and this needs to be done in my .cshrc file,
since aliases aren't inherited by children.  Some of my aliases make
use of the environment variables I set.  But since my .login gets run
*after* my .cshrc, I can't put these 'setenv' calls in my .login.

I tend to do things like the following example to get around this:

    # .cshrc file (extremely oversimplified) ...

    if (! ${?HOSTNAME}) then
    	#
    	# I don't want to call `hostname` every time I go to a
    	# subshell, since hostname is an external program and takes up
    	# system overhead.  My host name shouldn't change during the
    	# course of a login session.  I want to use $HOSTNAME in some
    	# of my aliases and to determine certain paths through my
    	# .cshrc logic.  This same thinking applies to certain other
    	# environment variables I set.
    	#
    	setenv HOSTNAME "`hostname`"
    	# etc. ...
    endif

    # alias settings go here
    # etc. ...

It would be nice if I could put the stuff between 'if (! ${?HOSTNAME}) ...'
and 'endif' into my .login file, and if .login would get sourced
before .cshrc, but I know this is impossible.  This is what inspired
my original question.

  >I end up doing things like the following hack ...
  >
  >    # This resides at the top of a hypothetical .cshrc file ...
  >
  >    if (! ${?FIRST_TIME_THROUGH}) then
  >    	setenv FIRST_TIME_THROUGH
  >    	# do all sorts of startup stuff that I would prefer to put
  >    	# into .login if it were only sourced before .cshrc
  >    endif
  
  What makes you think something gets executed twice?  ...

If I didn't have the 'if (! ${?FIRST_TIME_THROUGH) ...' logic bracketing
the '#do all sorts of startup stuff' logic, this 'startup stuff' would
get executed every time I entered a subshell or ran a csh script that
didn't begin with "#!/bin/csh -f".  I don't want this to happen.

  >Are there any csh's out there that do this differently, perhaps if some
  >command-line flag is set?
  
  As far as I can tell, all cshs do it this way (i.e. read .cshrc, then .login)
  because it makes sense.
  
But it doesn't make that much sense to me, given my above arguments, which
is what prompted my query here in the first place.

I'm quite willing to continue to make use of the method I outlined above
to make up for the fact that .login doesn't get sourced first.  But I'd
like to know if there's something I'm missing that would explain why
csh was designed to do it the way it does?
--
  Lloyd Zusman                          UUCP:   ...!ames!fxgrp!ljz
  Master Byte Software              Internet:   ljz%fx.com at ames.arc.nasa.gov
  Los Gatos, California               or try:   fxgrp!ljz at ames.arc.nasa.gov
  "We take things well in hand."



More information about the Comp.unix.questions mailing list