ProgrammingThis 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.
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.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
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?"
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.
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?"
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.
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.
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.
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).
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.
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.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.