ljz@fxgrp.UUCP (Lloyd Zusman) (05/21/88)
A question concerning csh: Can anyone explain why .login gets sourced *after* .cshrc? I am constantly running into situations where I'd like .login to get sourced first, and I cannot see any good reasons for why it should get sourced after .cshrc. I end up doing things like the following hack to get around this: # 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 ... Are there any csh's out there that do this differently, perhaps if some command-line flag is set? -- Lloyd Zusman UUCP: ...!ames!fxgrp!ljz Master Byte Software Internet: ljz%fx.com@ames.arc.nasa.gov Los Gatos, California or try: fxgrp!ljz@ames.arc.nasa.gov "We take things well in hand."
gandalf@csli.STANFORD.EDU (Juergen Wagner) (05/21/88)
In article <636@fxgrp.UUCP> ljz%fx.com@ames.arc.nasa.gov (Lloyd Zusman) writes: >A question concerning csh: > >Can anyone explain why .login gets sourced *after* .cshrc? I am constantly >running into situations where I'd like .login to get sourced first, and I >cannot see any good reasons for why it should get 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. >I end up doing things like the following hack to get around this: > > # 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? The csh reads .cshrc, i.e. sets up an environment suitable for your interactive needs, as well as for mail or the Liszt LISP compiler who fire up cshs. Then, your .login is source'd, thereby establishing all the things you need for a (now definitely interactive) session, like biff, stty, tset, ... Since environment variables are inherited from the parent's shell, you can set environment variables once in .login. So, I don't see any reason why you may want to have .login executed first. Maybe you could elaborate your point a bit. >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. -- Juergen "Gandalf" Wagner, gandalf@csli.stanford.edu Center for the Study of Language and Information (CSLI), Stanford CA
barnett@vdsvax.steinmetz.ge.com (Bruce G. Barnett) (05/21/88)
In article <636@fxgrp.UUCP> ljz%fx.com@ames.arc.nasa.gov (Lloyd Zusman) writes: |Can anyone explain why .login gets sourced *after* .cshrc? Probably because it makes sense. How else to you specify a command to execute automatically when you log in that changes your environment? Examples: emacs, X windows, suntools, screen-based applications, etc. I usually test for the value of prompt, user, and/or term in my .cshrc file. This way I can distinguish between a script, rcp/rsh, rlogin or login. This has always been sufficient for me. What are you doing that requires the opposite? (You can always do a 'source .my-login' in your .login file). -- Bruce G. Barnett <barnett@ge-crd.ARPA> <barnett@steinmetz.UUCP> uunet!steinmetz!barnett
gwyn@brl-smoke.ARPA (Doug Gwyn ) (05/21/88)
In article <636@fxgrp.UUCP> ljz%fx.com@ames.arc.nasa.gov (Lloyd Zusman) writes: >Can anyone explain why .login gets sourced *after* .cshrc? I am constantly >running into situations where I'd like .login to get sourced first, and I >cannot see any good reasons for why it should get sourced after .cshrc. You're right, and csh is wrong, but as you can imagine it cannot be changed now. >Are there any csh's out there that do this differently, perhaps if some >command-line flag is set? Not that I know of. The BRL Bourne shell equivalent feature (ENV file) does this right.
ljz@fxgrp.UUCP (Lloyd Zusman) (05/22/88)
In article <3990@csli.STANFORD.EDU> gandalf@csli.stanford.edu (Juergen Wagner) writes: In article <636@fxgrp.UUCP> ljz%fx.com@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@ames.arc.nasa.gov Los Gatos, California or try: fxgrp!ljz@ames.arc.nasa.gov "We take things well in hand."
gandalf@csli.STANFORD.EDU (Juergen Wagner) (05/22/88)
After my posting I have received a number of responses of the form "I am doing ... in my .cshrc, and also ... in .login, and for that I need .login executed before .cshrc." I don't believe there is the need to run .login before .cshrc. .cshrc is intended to initialize *EVERY* csh fired up (except those invoked with -f option), so subsequent programs run well. There is a clear distinction between things which are typically done in .cshrc and .login: .cshrc: setting umask setting up some environment variables like USER/LOGNAME/... which are supposed to be there in every environment. setting a (probably preliminary path/cdpath) setting csh variables providing aliases setting a (probably also preliminary) prompt. Never put in something setting the terminal, doing biff, echoing some text, etc. Remember: .cshrc is run every time a csh is fired up (by mail, emacs, X windows, LISP compilers, Prolog, ...) and should be as simple as possible (for obvious reasons). The case in which an interactive shell is started, can be recognized by using $?prompt conditionals. Oh, yes, and of course, the .cshrc *CAN* contain aliases and ways to set the prompt in a terminal dependent way. You just must not call them there. .login: set the terminal type and initialize the terminal set some globally defined environment variables like (EXINIT, EDITOR, VISUAL, EMACSLIB, EMACSLOADPATH, TEXLIB, ...) which should be accessible for all programs run interactively. You now may say "what if one needs these variables in a rsh, too". Well, in that case, execute a "source .login" before you actually run the desired program, and be sure your .login also does the $?prompt business. In my .login, all the machine/terminal/UNIX-version dependent things are done. This includes computing/fetching host/...-dependent values for some environment variables. Then, If you'd like to set your prompt depending on the terminal type (e.g. highlight some portions of it with terminal-specific control sequences), why don't you do this here. I can't remember the last time when I've exchanged the terminal just before running a new csh, so I don't see a need to do this in a fashion requiring to execute .login first. Either you are running with $?prompt==1, i.e. you can set the terminal-specific prompt wherever you want to, or you have $?prompt==0 and you don't have a terminal at all. Apologies for this message being so long but I have a final comment on my .login. The last two steps in my .login are o source a location-dependent .login (location=institute or something similar), and o read a host type dependent .login (host type is sun, vax, ...). This allows me to have the same rc files on all machines I'm working on, even if one is a Bobcat (HP-UX), one is a Sun 3, one is a Sun 4, another one is a VAX, ... A small configuration database consisting of some attribute lists and a couple of shell scripts provides this functionality, and I've been pretty happy with it. Of course, this doesn't claim to be an ideal solution to all problems but has been working fine. I'd love to hear of instances where it is impossible or unreasonable (i.e. requiring too much efforts) to get along with the .cshrc .login order of execution. All opinions expressed herein, even the most arbitrary, are defended by my employer with religious fervor. -- Juergen "Gandalf" Wagner, gandalf@csli.stanford.edu Center for the Study of Language and Information (CSLI), Stanford CA
barnett@vdsvax.steinmetz.ge.com (Bruce G. Barnett) (05/23/88)
In article <655@fxgrp.UUCP> ljz%fx.com@ames.arc.nasa.gov (Lloyd Zusman) writes: |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. You are trying to avoid extra overhead, but i believe you are doing it the wrong way. See below. |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? Usually people start up special applications in their .login file. Emacs, X windows, suntools, ... In fact, when you want the user to run a special application, you just modify the .login file. Yet anything in the .cshrc file is also executed. There are also times when you may want to allow a remote shell or copy, but no local login. Because .cshrc is sourced before .login, this is possible. You can have remote users/scripts that only run non-interactive, etc. But let's not start anything religious. If I understand what you want to do, I suggest you make use of site specific .cshrc files. e.g. if ( -e .my-cshrc && -o .my-cshrc ) source .my-cshrc Yes, this does mean you have to maintain an extra file. But you probably have to maintain some site dependancies somewhere. Use m4(1) or make(1) if you wish. I believe this will be much more efficient that what you are doing for the following reasons: 1. Sticking extra baggage in your environment variables means that each process has to copy the entire environment variable list for EACH PROCESS. This slows down each fork. Not just scripts. 2. Testing for the existance of a file should be faster than executing a program. (Okay, if all of your systems use the same NFS home directory, this wouldn't win. The file would always be there.) 3. Enclosing large lists of aliases in if/then blocks still requires the shell to scan past them even if they aren't going to use them. That is, the construct if ( $?prompt ) then # monster list of aliases ... endif is inefficient if the shell is not interactive. -- Bruce G. Barnett <barnett@ge-crd.ARPA> <barnett@steinmetz.UUCP> uunet!steinmetz!barnett
rgsmeb@abcom.ATT.COM (Michel Behna) (05/23/88)
From article <636@fxgrp.UUCP>, by ljz@fxgrp.UUCP (Lloyd Zusman): > A question concerning csh: > > Can anyone explain why .login gets sourced *after* .cshrc? I am constantly Excuse me for asking a stupid question, but why don't you move the code from one to the other? Would that solve yopur problem? -- Michel Behna rgsmeb@abcom.att.com | ihnp4!{ncsc1,codas}!abcom!rgsmeb " It is all right for man to make love, and it is all right for man to make war, but he shouldn't try to do both at the same time."
ljz@fxgrp.UUCP (Lloyd Zusman) (05/26/88)
In article <2791@abcom.ATT.COM> rgsmeb@abcom.ATT.COM (Michel Behna) writes: From article <636@fxgrp.UUCP>, by ljz@fxgrp.UUCP (Lloyd Zusman): > Can anyone explain why .login gets sourced *after* .cshrc? I am constantly Excuse me for asking a stupid question, but why don't you move the code from one to the other? Would that solve yopur problem? No, because .login only gets sourced when you first log in, but .cshrc gets sourced whenever a shell is started up. The latter can take place more than once per login session, and it usually does. Hence, different types of information are put into the two files. It's not a stupid question. -- Lloyd Zusman UUCP: ...!ames!fxgrp!ljz Master Byte Software Internet: ljz%fx.com@ames.arc.nasa.gov Los Gatos, California or try: fxgrp!ljz@ames.arc.nasa.gov "We take things well in hand."
strong@tc.fluke.COM (Norm Strong) (05/26/88)
In article <636@fxgrp.UUCP> ljz%fx.com@ames.arc.nasa.gov (Lloyd Zusman) writes: }A question concerning csh: } }Can anyone explain why .login gets sourced *after* .cshrc? I am constantly }running into situations where I'd like .login to get sourced first, and I }cannot see any good reasons for why it should get sourced after .cshrc. } Why not put the contents of your .login file in your .cshrc file? -- Norm (strong@tc.fluke.com)
dg@lakart.UUCP (David Goodenough) (05/31/88)
>In article <636@fxgrp.UUCP> ljz%fx.com@ames.arc.nasa.gov (Lloyd Zusman) writes: >}A question concerning csh: >}Can anyone explain why .login gets sourced *after* .cshrc? I am constantly >}running into situations where I'd like .login to get sourced first, and I >}cannot see any good reasons for why it should get sourced after .cshrc. > And in article <3872@fluke.COM>, strong@tc.fluke.COM (Norm Strong) replies: > Why not put the contents of your .login file in your .cshrc file? The reason that I believe it is done is to allow such things as unset ignoreeof # in ~/.cshrc and then set ignoreeof # in ~/.login Now this means that in all your c-shells except your login shell will respect a ^D to exit, but you explicitly have to say "logout" or "exit" to your login shell to get it to go away i.e. hammering ^D will return you to your login shell but will stop there. The basic notion is that you set your environment with .cshrc, and thene make any login shell changes (and of course login only commands) in your .login. Now if anyone knows different they will doubtless speak up :-) :-) -- dg@lakart.UUCP - David Goodenough +---+ | +-+-+ ....... !harvard!adelie!cfisun!lakart!dg +-+-+ | +---+
gph@hpsemc.HP.COM (Troutfishing in America) (06/04/88)
Lloyd Zusman writes:
-->Are there any csh's out there that do this differently, perhaps if some
-->command-line flag is set?
----------
Lloyd,
I think you have a very good point. It's interesting that the new
Korn shell, which I view as an improvement over csh, first executes
.profile, and then executes .kshrc. .kshrc is executed with each
invocation of a ksh.
This is exactly the scenario you want for your csh.
I use ksh, and this way is quite satisfactory.