Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!wuarchive!uunet!escob1!dickson From: dickson@escob1.UUCP (Dave Dickson) Newsgroups: comp.unix.shell Subject: Re: How does the ksh ENV "trick" work? Message-ID: <1345@escob1.UUCP> Date: 27 May 91 13:49:10 GMT References: <1991May27.054451.24232@brolga.cc.uq.oz.au> Organization: Ohio Bell Telephone, (Eng'ng) , Columbus, OH Lines: 149 eric@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