We help IT Professionals succeed at work.

how to differentiate in a program whether it has been called from a shell or using exec

ahts
ahts asked
on
Hi all,

say I want to make a program "abc" which should give different print outs in the following two situations

case I
-------
bash# ./abc
The parent is a shell
bash#


case II
--------

bash# exec ./abc
the parent is the parent of bash
Connection closed by foreign host.
$ >

if we were using the telnet session or

bash# exec ./abc
the parent is the parent of bash

login:

if we are running the program from console.

I mean while executing abc using "exec", abc will take over bash. so you will be logged out from the current session.

So some how I have to differentiate in my program "abc" whether this has been called after exec or not.
1. how to achieve this ??
or
2. what are the parameters which we can check in our program to achieve it ?
The solution has to be the shell independent so that it should not matter whether we are using a bash or csh or any other shell.

Thanks in advance
Ashutosh
Comment
Watch Question

CERTIFIED EXPERT

Commented:
man getppid
Also use tty and check the return status to see if it came from a window (I assume that the parent program is a daemon of some kind).  It will return 0 if the terminal is a window, and 1 if it's not.
Commented:
There is no foolproof method of determining which of the two invocation methods was used from within the program.

The solution I would recommend would be to supply a command line option which the program would use to determine this. You'll just have to just that the user/script-writer used the option appropriately

Commented:
what happens if:
     bash invokes bash invokes the program?
Then the parent of bash is bash.

You can "make magic happen" by expanding
the exec builtin (perhaps modifying the environment)

bash5 :5 leisner@thingy; type -a exec
exec is a function
exec ()
{
    export DIDEXEC=true;
    builtin exec $*
}


bash5 :5 leisner@thingy; type -a exec
exec is a function
exec ()
{
    export DIDEXEC=true;
    builtin exec $*
}
exec is a shell builtin
bash5 :5 leisner@thingy; printenv DIDEXEC
bash5 :5 leisner@thingy; exec !printenv
exec printenv DIDEXEC
true
bash4 :4 leisner@thingy;

But this relies on cooperation -- same problem if an
arbitrary program fork/execs -- how can you differentiate
a fork/exec from a straight exec?  (without knowing information about the past history of the system).

Author

Commented:
HI leisner,

This seems to be good if you are working in only bash shell. I was thinking of a solution which is shell independent, because you never know which shell the user is using.

I think the print statments in the example I have given in my problem is confusing and it seems that I want a solution for bash only.

Any suggestions if we can make it shell independent??

-Ashutosh

Author

Commented:
HI leisner,

This seems to be good if you are working in only bash shell. I was thinking of a solution which is shell independent, because you never know which shell the user is using.

I think the print statments in the example I have given in my problem is confusing and it seems that I want a solution for bash only.

Any suggestions if we can make it shell independent??

-Ashutosh

Author

Commented:
HI leisner,

This seems to be good if you are working in only bash shell. I was thinking of a solution which is shell independent, because you never know which shell the user is using.

I think the print statments in the example I have given in my problem is confusing and it seems that I want a solution for bash only, but in the end I clearly mentioned that solution has to be shell independent.

Any suggestions if we can make it shell independent??

-Ashutosh

Author

Commented:
HI leisner,

The answer you have proposed seems good if you are working only in bash shell. I was thinking of a solution which is shell independent, because you never know which shell the user is using.

I think the print statments in the example I have given in my problem is confusing and it seems that I want a solution for bash only, but in the end I clearly mentioned that solution has to be shell independent.

Any suggestions if we can make it shell independent??

-Ashutosh

Author

Commented:
This seems that there was some problem (somewhere) when I was trying to add the comment and it has been added four times..  and there is no option to delete the comment. ooops!!!

-Ashutosh
CERTIFIED EXPERT

Commented:
id you check getppid() ?

Author

Commented:
Hi ahoffmann,

what would I get from getppid(), only the pid of the parent. but this is not usefull in my case. If I go about searching for the process which has got this pid... and if this is a bash, or csh or ksh or sh or ..............
this is not a good solution...

CERTIFIED EXPERT

Commented:
> .. and if this is a bash, or csh or ksh
it isn't any shell if it was called by exec !!
The parrenbt process doesn't exist after an exec, 'cause it was replaced by exec. In this case UNIX uses PID 0 (or that of init process, differs on some UNIXs) as parent PID.
You understand?

Commented:
I don't believe that is correct ahoffmann. An 'exec' _replaces_ the current process with a new one -- it does not destroy any processes.

ie. A shell with the PID of 1000 execs 'abc'. The PID of 'abc' will be 1000 and its parent will be the parent of the original shell.

I stand by my original suggestion.
jmcgOwner
CERTIFIED EXPERT

Commented:
No comment has been added lately, so it's time to clean up this TA.
I will leave the following recommendation for this question in the Cleanup topic area:

Accept: MFCRich {http:#6544740}

Please leave any comments here within the next seven days.
PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!

jmcg
EE Cleanup Volunteer

Explore More ContentExplore courses, solutions, and other research materials related to this topic.