How does the ksh ENV "trick" work?

Dave Dickson dickson at escob1.UUCP
Mon May 27 23:49:10 AEST 1991


eric at brolga.cc.uq.oz.au (Eric Halil) writes:

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

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

>as a easy way to stop your .kshrc being evaluated when it's an not an
>interactive shell.  Can someone explain in detail how this works? 

I asked myself the same thing one time and spent an hour or so figuring
it out.  I knew that I would not be able to remember how it worked, so
I wrote up the following. I hope this helps.


EXAMPLE from "The KORNSHELL Command and Programming Language"
	by David G. Korn:

START=~/.alias; export START
ENV='${START[(_$-=0)+(_=1)-_${-%%*i*}]}'


ENV can be set to so that it evaluates to a Null value if you
are in a non-interactive shell, or to a file name if in an
interactive shell.  The procedure is shown in "The KORNSHELL
Command and Programming Language" by David G.  Korn; however,
Korn gives no explanation as to how this works, this is an
attempt to explain it.

The assignment of a variable for the "Alias" file is straight
forward and requires no explanation.  (In the example "FILE" is
used, however, I will use "START," i.e., START=~/.alias; export
START.)  The evaluation of the subscript for "START" is the part
that requires an explanation.

The trick is to get the subscript for START to evaluate to a "0"
for an interactive shell and to a "1" for non-interactive shells,
thus ENV would be set to START[0] (~/.alias) for an interactive
shell, but would be set to "START[1]" (Null) for a
non-interactive shell.


Before we get started a couple of points should be made:

1) Within a subscript, arithmetic evaluation is used, meaning
that variable names (named parameters) and constants are treated
the same as within "((...))"  and hence, don't need to be
preceded by "$."

2) Because of the "'" (single quote),
'${START[(_$-=0)+(_=1)-_${-%%*i*}]}' is not evaluated until "ENV"
is referenced by the shell.

3) The "_" used in the statement is simply an identifier, just
like any other identifier and just as well could have been X, or
whatever.

4) Parameter "$-" holds the value of the Option Flags supplied
to KSH at invocation.  $- will include an "i" if interactive; if
the shell is non-interactive, no "i" will be present in parameter
$-.

5) It is important to understand that the evaluation of "var1"
and "var2", below, is always set to "0" and "1" respectively (the
names are set and the value assigned in one statement).


The statement is easier to understand, if you break the
subscript arithmetic down into 3 parts, "var1", "var2" and
"var3":

	var1)	"_$-=0"
	var2)	"_=1"
	var3)	"_${-%%*i*}"

and look at the evaluation of the subscript as being equal to:

	var1+var2-var3

or, START[var1 + var2 - var3].

EXAMPLE for an interactive shell with Option Flags imsh:

var1:
		"$-" evaluates to "imsh", a "_" is prepended to it and it is
		assigned the value of "0".  So, we now have a variable with
		a name of "_imsh" and it is set to "0":

		_imsh=0

var2:
		"_" is set to "1":

		_=1

var3:
		Var3 is set to "_" with the result of parameter deletion
		( ${-%%*i*} ) appended to it.  Since "$-" has an "i" in it,
		the result of the parameter deletion is Null, meaning that
		var3 is named "_", which has a value of "1":

		_		(this has a value of "1", see var2: above)


Evaluation:
	
	ENV='${START[(_$-=0)+(_=1)-_${-%%*i*}]}' ;
	ENV=${START[(_imsh)+(_)-_]}
	ENV=${START[(0)+(1)-1]}
	ENV=${START[0]}
	ENV=~/.alias


EXAMPLE for an non-interactive shell with Option Flags h:

var1:
		"$-" evaluates to "h", a "_" is prepended to it and it is
		assigned the value of "0".  So, we now have a variable with
		a name of "_h" and it is set to "0":

		_h=0

var2:
		"_" is set to "1":

		_=1

var3:
		Var3 is set to "_" with the result of parameter deletion
		( ${-%%*i*} ) appended to it.  Since "$-" has no "i" in it,
		there is no parameter deletion done meaning "var3" is named
		"_h", which has a value of "0":

		_h		(this has a value of "0", see var1: above)


Evaluation:
	
	ENV='${START[(_$-=0)+(_=1)-_${-%%*i*}]}' ;
	ENV=${START[(_h)+(_)-_h]}
	ENV=${START[(0)+(1)-0]}
	ENV=${START[1]}
	ENV=
-- 
David G. Dickson
Ohio Bell Telephone Co. (614-223-8134)
uunet!escob1!dickson



More information about the Comp.unix.shell mailing list