Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game. |
| Notices |
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
Are you new to LinuxQuestions.org? Visit the following links:
Site Howto |
Site FAQ |
Sitemap |
Register Now
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
 |
GNU/Linux Basic Guide
This 255-page guide will provide you with the keys to understand the philosophy of free software, teach you how to use and handle it, and give you the tools required to move easily in the world of GNU/Linux. Many users and administrators will be taking their first steps with this GNU/Linux Basic guide and it will show you how to approach and solve the problems you encounter.
Click Here to receive this Complete Guide absolutely free. |
|
 |
07-22-2005, 05:20 PM
|
#1
|
|
LQ Newbie
Registered: Jul 2005
Distribution: Slack, LFS, "other"
Posts: 10
Rep:
|
Predict child PID
Hi all,
I'm trying to write a script that executes another script with the same PID of the parent. I've found using exec keeps the PID's the same, however once the new command is spawned, I don't know how to get the parent script to continue when the child is done. I've searched, read, and reviewed, but must be missing something. Here's an example:
Code:
#!/bin/bash -x
echo "Parent PID: $$"
exec echo "Baby PID: $$"
echo "Where did it go George?"
Here is what I get:
Code:
03:20:24 /usr/wrappers #-> ./test
+ echo Parent PID: 2222
Parent PID: 2222
+ exec echo 'Baby PID:2222'
Baby PID:2222
Echo may be a weak example, I'm actually executing another script, but my problem is where the last line is. I want the "Where did it go George" to echo when the exec'd process is done. Also open to any other ways to do this, I just want to know the PID of the child BEFORE its executed.
Thanks
|
|
|
|
07-22-2005, 07:23 PM
|
#2
|
|
LQ Newbie
Registered: Jul 2005
Distribution: Slack, LFS, "other"
Posts: 10
Original Poster
Rep:
|
Ok, got something going, kind of a &#ck around, but it should work.
Code:
#!/bin/bash -x
echo Parent PID: $$
function george
{
while $(ps -ef | grep -m 1 $$ &>/dev/null); do
sleep 1;
done
echo "Got ya George"
exit 0;
}
george&
exec echo "Baby PID:$$"
echo "Where did it go George?"
This gives me this:
Code:
05:28:08 ~/hailstorm/wrappers #-> ./test
+ echo Parent PID: 2650
Parent PID: 2650
+ exec echo 'Baby PID:2650'
+ george
Baby PID:2650
05:28:59 ~/hailstorm/wrappers #-> ++ ps -ef
++ grep -m 1 2650
+ sleep 1
++ ps -ef
++ grep -m 1 2650
+ echo 'Got ya George'
Got ya George
+ exit 0
I can use that to predict the PID of the process that I exec, and put any commands I want to execute upon it's closing after the loop. Kind of a wierd way to do it but it works. If theres a damn builtin or common command to do something like this, please let me know.
|
|
|
|
07-23-2005, 02:10 AM
|
#3
|
|
Member
Registered: Jun 2005
Posts: 75
Rep:
|
There is a bash built-in called wait that's supposed to wait for a process to finish. See help wait in bash for more info.
Code:
echo "Where did it go George?"
Any code after an exec will never be executed because the image of the exec'ing process is replaced by the image of the exec'd process.
~sind
|
|
|
|
07-23-2005, 12:30 PM
|
#4
|
|
LQ Newbie
Registered: Jul 2005
Distribution: Slack, LFS, "other"
Posts: 10
Original Poster
Rep:
|
Thanks Mate,
That would help me execute the commands after the child process if I didn't use exec, but I have to use exec because that's the only way I know of to keep the child processes PID predictable. Here is a more real world example of what I'm trying to do.
Code:
#!/bin/bash
# Make this PID available to ALL children.
export PID=$$
# Load iptables rules to allow whois, including a match for PID using the exported variable.
/wherever/whois_rules accept
function after_exec
{
while $(ps -ef | grep -m 1 $PID &>/dev/null); do
sleep 1;
done
# Delete iptables rules when whois process is complete.
/wherever/whois_rules delete
exit 0;
}
# Execute in background to let the script continue while still testing for completion.
after_exec&
# Run whois program.
exec /usr/bin/whois $*
Your definately right about not being able to put commands after the exec (wish I knew that before my first post, duh), but now if I put them in the after_exec function, they will technically execute after exec, and I can let the iptables script know what the PID of the whois command is going to be through the $PID variable. Kind of wierd I guess. Anyways, thanks for your time man.
|
|
|
|
07-24-2005, 05:22 PM
|
#5
|
|
Member
Registered: May 2005
Posts: 378
Rep:
|
Quote:
|
That would help me execute the commands after the child process if I didn't use exec, but I have to use exec because that's the only way I know of to keep the child processes PID predictable. Here is a more real world example of what I'm trying to do.
|
The PID isn't predictable in a multi-user system like Linux. Your child process will get a different PID from the parent, the only reason your script is showing the same PID for the child is that you're printing the PID of the shell, not the child process. You can kick off a process in the background in a shell and get its PID by $!. Save $! into a variable (CHILDPID=$!) and then use "wait $CHILDPID" to know when it's terminated.
|
|
|
|
07-24-2005, 08:17 PM
|
#6
|
|
LQ Newbie
Registered: Jul 2005
Distribution: Slack, LFS, "other"
Posts: 10
Original Poster
Rep:
|
I thought the script creates a new shell (and PID) when called by the interpreter, and the exec'd process just takes over the current shell (PID) when called by exec, keeping it the same (that's what I mean by predictable).
|
|
|
|
07-24-2005, 08:48 PM
|
#7
|
|
LQ Newbie
Registered: Jul 2005
Distribution: Slack, LFS, "other"
Posts: 10
Original Poster
Rep:
|
Sorry for the double post, but here's a quick example to back up my theory:
$SHLVL is a shell status variable that expands to the current shell depth
$$ expands to the current PID
file 1 is "lvltest"
Code:
#!/bin/bash -x
echo $SHLVL
echo $$
./lvltest2
exec ./lvltest2
file 2 is "lvltest2"
Code:
#!/bin/bash -x
echo $SHLVL
echo $$
output of "lvltest"
Code:
06:46:39 ~/hailstorm/wrappers #-> ./lvltest
+ echo 6
6
+ echo 2311
2311
+ ./lvltest2
+ echo 7
7
+ echo 2312
2312
+ exec ./lvltest2
+ echo 6
6
+ echo 2311
2311
06:49:00 ~/hailstorm/wrappers #->
The unexec'd lvltest2 causes the PID and shell depth to increment by one. The PID can probably increment by a lot more than one if a lot of stuff is going on on your system. However when I use exec, the PID is the same as the parent, instead of creating a subshell, it just takes over. As sind pointed out earlier. So by picking off the PID early in the calling script, I know what PID any program I want to execute will be.
If I used the $! (which I didn't know about, thanks) and wait builtin, I wouldn't be able to use the $CHILDPID variable in iptables scripts prior to execution. The match I'm using is -m owner --pid-owner. Also, if I executed something like whois in the background, I wouldnt see the output.
Anyways, I got it working as I had wanted to, and learned a whole lot in the process, which was the main goal. Once again, I appreciate the responses and expertise.
|
|
|
|
07-30-2005, 05:11 PM
|
#8
|
|
Member
Registered: May 2005
Posts: 378
Rep:
|
Yes, but in your first script you have the line
Code:
exec echo "Baby PID: $$"
This will expand the $$ before the exec is performed, so you're printing the PID of the parent, as I said. Because the exec replaces the original process, it'll get the same PID, but the one your echo is printing is the parent's, not its own (if you understand the semantic difference).
Last edited by eddiebaby1023; 07-30-2005 at 05:14 PM.
|
|
|
|
| Thread Tools |
Search this Thread |
|
|
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
All times are GMT -5. The time now is 10:59 AM.
|
|
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.
|
Latest Threads
LQ News
|
|