Summary: Solutions to the Shell Level question.
Charles Lambert
chas at ihuxe.UUCP
Sat Feb 2 11:25:38 AEST 1985
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
More information about the Comp.unix
mailing list