[comp.unix.questions] ENV file in ksh: is this smart? legal?

jdpeek@rodan.acs.syr.edu (Jerry Peek) (08/31/89)

Two questions about things in ksh that don't seem to be answered in TFM.
We've got ksh Version 06/03/86a on a Gould NP1, UTX/32 (BSD-like).
[This is a re-post of a message that didn't get out before, I think.
Our news posting was set up wrong.  Sorry if you've seen this.]

#1.  I want it my ENV file to act like the ".cshrc" file in csh --
to be read anytime a new, interactive shell starts.
So, I have my ENV variable set this way in .profile:
	ENV='$HOME/.kshrc'; export ENV
The filename is in single-quotes.  That way, when I run the 'su'
command to start a shell on another account, the ksh on *that* account
will read the .kshrc file for *that* account's $HOME.  (If I'd used
double-quotes, the *same* .kshrc file would be read for *all* accounts.)
So now, each time I start a shell, it reads that account's $HOME/.kshrc.

Anybody see problems, or know another way to make this work?

#2.  The next problem I have with ENV files -- if their name is stored
in the environment (export ENV) -- is that Korn shell script files
(shell programs) read them too.  I have some stuff in my ENV file that
screws up shell scripts.

Here's how I fixed the problem.  I put this at the start of my ENV file:
	case "$-" in
	*i*) ;;	# IF SHELL IS INTERACTIVE, READ THIS FILE
	*) return ;; # ELSE, EXIT AND DON'T READ IT
	esac
It works.  For non-interactive shells, the ENV file isn't read --
and the rest of the shell program runs just fine, like I want.

The problem is, TFM doesn't seem to say whether that's legal.  It says:
	- If return is invoked while not in a function or a script,
	  then it is the same as an exit .
	- exit n  Causes the shell to exit with the exit status specified by n.
The first one says that return inside a script is not the same as exit,
but it doesn't say *how* it's different.  (Is an 'ENV' file a "script?")
Anyhow, am I doing anything that I'll regret? :-)

Thanks...

--Jerry Peek; Syracuse University Academic Computing Services; Syracuse, NY
  jdpeek@rodan.acs.syr.edu///jdpeek@sunris.bitnet///GEnie: J.PEEK1
  +1 315 443-3995

gwyn@smoke.BRL.MIL (Doug Gwyn) (08/31/89)

In article <716@rodan.acs.syr.edu> jdpeek@rodan.acs.syr.edu (Jerry Peek) writes:
>#2.  The next problem I have with ENV files -- if their name is stored
>in the environment (export ENV) -- is that Korn shell script files
>(shell programs) read them too.  I have some stuff in my ENV file that
>screws up shell scripts.

That's a Korn shell design botch.  Apparently DGK thought that the C shell
behavior should be mimicked.  Too bad he didn't first notice what a pain
it already was for C shell users.  When Doug Kingston and I added a
similar feature to the BRL Bourne shell, we were more careful, and I think
ours works right.  It does NOT get sourced for shell scripts (unless they
decide to source the file themselves, which would be exceedingly rare).

vinoski@apollo.HP.COM (Stephen Vinoski) (09/01/89)

In article <716@rodan.acs.syr.edu> jdpeek@rodan.acs.syr.edu (Jerry Peek) writes:
>#2.  The next problem I have with ENV files -- if their name is stored
>in the environment (export ENV) -- is that Korn shell script files
>(shell programs) read them too.  I have some stuff in my ENV file that
>screws up shell scripts.
>
>Here's how I fixed the problem.  I put this at the start of my ENV file:
>	case "$-" in
>	*i*) ;;	# IF SHELL IS INTERACTIVE, READ THIS FILE
>	*) return ;; # ELSE, EXIT AND DON'T READ IT
>	esac

From "The Kornshell Command and Programming Language" by Morris I. Bolsky and
David G. Korn, Prentice-Hall, 1989, ISBN 0-13-516972-0, page 78:

export FILE=$HOME/.envfile
# The subscript below evaluates to 0 when interactive.
ENV='${FILE[(_$-=0)+(_=1)-_${-%%*i*}]}'

This way ENV expands to null when the shell is not interactive.  I use this and
it works perfectly.

I also highly recommend the book - it's a great reference with some really good
examples of the power of the Kornshell.


-steve
-- 
# Steve Vinoski       # Apollo, a Subsidiary of HP  # ARPA: vinoski@apollo.com #
# (508)256-6600 x5904 # Chelmsford, MA  01824       # UUCP: ...!apollo!vinoski #
# "...no hardware designer should be allowed to produce any piece of hardware  #
#  until 3 software guys have signed off for it."   -Andy Tanenbaum            #

chet@kiwi.CWRU.EDU (Chet Ramey) (09/03/89)

In article <716@rodan.acs.syr.edu> Jerry Peek complains about ksh sourcing
the $ENV file for all invocations of shell scripts, interactive or not.

Doug Gwyn replies:

>That's a Korn shell design botch.  Apparently DGK thought that the C shell
>behavior should be mimicked.  Too bad he didn't first notice what a pain
>it already was for C shell users.  When Doug Kingston and I added a
>similar feature to the BRL Bourne shell, we were more careful, and I think
>ours works right.  It does NOT get sourced for shell scripts (unless they
>decide to source the file themselves, which would be exceedingly rare).

I think there might be an additional reason Korn did it that way: because
the Korn Shell does not provide exportable shell functions.  Using ksh, the
only way to have your personal shell functions (which are assumed to be
defined in the $ENV file) available when executing a script is to source
the $ENV file for every ksh invocation.  (The BRL Bourne Shell doesn't let
you export functions to a sub-shell either, so its users have the same
problem.)

You could argue that shell scripts that want or need these functions should
source the necessary files themselves (and I would agree with you), but
maybe Korn thought otherwise when he put the feature into ksh. 

(I can't resist a plug).  In BASH, the Gnu Bourne-Again SHell, functions are
exportable.  Version 1.03 was just released, grab it from prep.ai.mit.edu.

Chet Ramey (a bash contributor)
Chet Ramey			"We are preparing to think about contemplating 
Network Services Group, CWRU	 preliminary work on plans to develop a
chet@cwjcc.INS.CWRU.Edu		 schedule for producing the 10th Edition of 
				 the Unix Programmers Manual." -- Andrew Hume

gwyn@smoke.BRL.MIL (Doug Gwyn) (09/03/89)

In article <526@cwjcc.CWRU.Edu> chet@kiwi.INS.CWRU.Edu (Chet Ramey) writes:
>I think there might be an additional reason Korn did it that way: because
>the Korn Shell does not provide exportable shell functions.  Using ksh, the
>only way to have your personal shell functions (which are assumed to be
>defined in the $ENV file) available when executing a script is to source
>the $ENV file for every ksh invocation.  (The BRL Bourne Shell doesn't let
>you export functions to a sub-shell either, so its users have the same
>problem.)
>You could argue that shell scripts that want or need these functions should
>source the necessary files themselves (and I would agree with you), but
>maybe Korn thought otherwise when he put the feature into ksh. 

As a security measure, I think it is ESSENTIAL that ordinary shell scripts
not import aliases, functions, IFS, PATH, or other things that could cause
unintended behavior.  PATH is easy to fix in the script, and all ours do,
but the others are harder and should not be allowed to occur in the first
place.  Recent BRL Bourne shells do not import IFS, and modulo a bug that's
now been fixed they've never tried to source the $ENV file for scripts.
The BRL shell sources the $ENV file for interactive shells (only).  Most
of us keep our shell functions in a file ~/.funcs that the $ENV file
(typically named ~/.env) sources if it exists.  I also keep my command-
line editing key bindings in a separately sourceable file ~/.shbind.  If
some such convention were adopted sitewide, then shell scripts that felt
it appropriate could source the user's shell definition files.  However,
I can't think of many non-interactive circumstances where that's appropriate.

>(I can't resist a plug).  In BASH, the Gnu Bourne-Again SHell, functions are
>exportable.  Version 1.03 was just released, grab it from prep.ai.mit.edu.

I considered doing that for the BRL shell, using the 9th Edition UNIX
syntax for the environment variables, but discovered that it caused
problems for existing (Bourne) shells and backed it out.  Of course it
still would have been limited to interactive shells.  The overhead of
sourcing $ENV as opposed to carrying the LARGE amount of extra environment
around with every process seems to be a good trade-off.

les@chinet.chi.il.us (Leslie Mikesell) (09/04/89)

In article <10920@smoke.BRL.MIL> gwyn@brl.arpa (Doug Gwyn) writes:

>The overhead of
>sourcing $ENV as opposed to carrying the LARGE amount of extra environment
>around with every process seems to be a good trade-off.

Is this still true if you have fork() with copy-on-write?

Les Mikesell