[net.unix] Summary: Solutions to the Shell Level question.

chas@ihuxe.UUCP (Charles Lambert) (02/02/85)

Thanks to all those people who took the trouble to reply to
my enquiry.  My problem was:

   How to determine whether I am currently executing in the
   initial shell (the one exec'd by login) or in a sub-shell.

Reason:

   I want my shell script to behave differently (eg. not "exit",
   or not "exec") if it's invoked by the "." command.

Here's a summary of the solutions I received.  I'm referring only
to the Bourne shell as available with System V or V.2.  For 
proprietary reasons I've not included the solutions for Korn
shell;  interested parties should read att.unix newsgroup.

TEST $0

When the login process execs your primary shell, it somehow causes
$0 to have the form "-{shellname}" ;  in practice this will be "-sh"
on most systems using the Bourne shell (?). Any subshell which is
executing a shell script will have $0 = "{script_name}".

So conditional statements such as:

	if [ "$0" = "-sh" ]
or
	case "$0" in
	-sh)

should fill the requirement.

CAVEAT: This will work in most circumstances, but is not bomb-proof.
	If, for instance, you switch from Bourne shell to C-shell
	and then back by means of "exec", you will find that $0
	has disappeared and the above tests will then fail.

FIND THE PARENT PID

Your primary shell is exec'd by the login process, which is ALWAYS a
child of process No.1 (the system initialisation process).  Hence, if
a shell can discover the PID of it's parent (PPID) it can determine
whether it is a primary shell or not.

The command "ps -l" will produce a verbose listing which contains
the PID (4th field of the line) and PPID (5th field) of each
active process. Since a shell knows its own PID ($$) it can find its
own entry in the list and extract the PPID.

The following pipelines will return status 0 (UNIX 'TRUE') if the
current shell is the primary shell, non-0 (UNIX 'FALSE') otherwise.
They can be used as Boolean expressions in a shell conditional statement.

	test `ps -l | awk '$4 == "'$$'" { print $5 }'` = "1" 
or
	[ `ps -l | awk '$4 == "'$$'" { print $5 }'` = "1" ]

(I make no apology for the opaque syntax of "awk" expressions, I don't
 support the damned thing.)

CAVEAT: This can be very slow, "ps" at my site seems to have been "nice"d
	almost to the point of non-execution.  However, it should be
	a lot more difficult to fool than the $0 test. (I await the
	deluge of mail, pointing out some blatant loophole.)

Charles Lambert
AT&T Bell Labs
Naperville, IL.
(...)!ihnp4!ihuxe!chas