Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > PID of exec

Reply
Thread Tools

PID of exec

 
 
hendedav@gmail.com
Guest
Posts: n/a
 
      10-25-2007
Gang,

I have looked all over google groups on how to find the pid of
the exec command when using the fork/exec. I will admit that I am not
overly familiar with the workings (I understand the idea though) of
these two commands. Here is what I am working with. I have a perl
script (see below) that calls a shell script that simply counts to
thirty while pausing for one second (basically is a script that does
nothing for 30 seconds so I can see if the PID is correct). What I am
trying to accomplish is trying to find the pid of the binary/script
that is executed from the exec command. If I run the script below,
this would be a sample of what I get:


debian:/tmp# ./test.pl
pid is 6330, parent pid is 6329
debian:/tmp# ps a
PID TTY STAT TIME COMMAND
2545 tty1 Ss+ 0:00 /sbin/getty 38400 tty1
2546 tty2 Ss+ 0:00 /sbin/getty 38400 tty2
2547 tty3 Ss+ 0:00 /sbin/getty 38400 tty3
2548 tty4 Ss+ 0:00 /sbin/getty 38400 tty4
2551 tty5 Ss+ 0:00 /sbin/getty 38400 tty5
2552 tty6 Ss+ 0:00 /sbin/getty 38400 tty6
2569 pts/1 Ss 0:00 -bash
2578 pts/1 S 0:00 bash
3104 pts/0 Ss+ 0:00 -bash
6331 pts/1 S 0:00 /bin/sh ./test.sh
6346 pts/1 S 0:00 sleep 1
6347 pts/1 R+ 0:00 ps a

As you can see neither of the pids is the one from the exec command.
I also tried using the open command (which returns the pid correctly),
but I can not background the process (using an & at the end of the
command). I need to find the pid of the exec command within the
parent perl script so that I can track it. Any help would greatly be
appreciated.

Thanks,
Dave

#!/usr/bin/perl

if (defined (my $pid = fork)) {
if ($pid) { # this test runs if the fork was successful
# eliminates the zombies
local $SIG{CHLD} = "IGNORE";
print "pid is $pid\n, parent pid is $$\n";
} else { # the following line runs in the child
exec("./test.sh &");
print "child pid is: $$\n";
exit();
}
} else {
print "there was a problem executing the script\n";
}

 
Reply With Quote
 
 
 
 
Peter Makholm
Guest
Posts: n/a
 
      10-25-2007
http://www.velocityreviews.com/forums/(E-Mail Removed) writes:

> As you can see neither of the pids is the one from the exec command.


exec() does not spawn a new process and do therefore not generate a
new process id. The exec function does never return so you 'print
"child pid is $$\n' statement is never executed (why didn't you winder
about this?).

> #!/usr/bin/perl
>
> if (defined (my $pid = fork)) {
> if ($pid) { # this test runs if the fork was successful
> # eliminates the zombies
> local $SIG{CHLD} = "IGNORE";
> print "pid is $pid\n, parent pid is $$\n";
> } else { # the following line runs in the child
> exec("./test.sh &");
> print "child pid is: $$\n";


Try to exchange the above two lines of code and se if you don't get an
pid for the child which matches what test.sh have.

> exit();
> }
> } else {
> print "there was a problem executing the script\n";
> }


//Makholm
 
Reply With Quote
 
 
 
 
hendedav@gmail.com
Guest
Posts: n/a
 
      10-25-2007
On Oct 25, 1:33 pm, Peter Makholm <(E-Mail Removed)> wrote:
> (E-Mail Removed) writes:
> > As you can see neither of the pids is the one from the exec command.

>
> exec() does not spawn a new process and do therefore not generate a
> new process id. The exec function does never return so you 'print
> "child pid is $$\n' statement is never executed (why didn't you winder
> about this?).
>
> > #!/usr/bin/perl

>
> > if (defined (my $pid = fork)) {
> > if ($pid) { # this test runs if the fork was successful
> > # eliminates the zombies
> > local $SIG{CHLD} = "IGNORE";
> > print "pid is $pid\n, parent pid is $$\n";
> > } else { # the following line runs in the child
> > exec("./test.sh &");
> > print "child pid is: $$\n";

>
> Try to exchange the above two lines of code and se if you don't get an
> pid for the child which matches what test.sh have.
>
> > exit();
> > }
> > } else {
> > print "there was a problem executing the script\n";
> > }

>
> //Makholm


I switched the two lines of code as suggested, and I did get a print
out, but it contained the same PID as the "my $pid=fork" statment.
Here is the output:

debian:/tmp# ./test.pl
child pid is: 6498
fork pid is 6498, parent pid is 6497
debian:/tmp# ps au
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 2545 0.0 0.2 1576 492 tty1 Ss+ Oct24 0:00 /sbin/
getty 38400 tty1
root 2546 0.0 0.2 1576 492 tty2 Ss+ Oct24 0:00 /sbin/
getty 38400 tty2
root 2547 0.0 0.2 1576 488 tty3 Ss+ Oct24 0:00 /sbin/
getty 38400 tty3
root 2548 0.0 0.2 1580 496 tty4 Ss+ Oct24 0:00 /sbin/
getty 38400 tty4
root 2551 0.0 0.2 1580 496 tty5 Ss+ Oct24 0:00 /sbin/
getty 38400 tty5
root 2552 0.0 0.2 1580 496 tty6 Ss+ Oct24 0:00 /sbin/
getty 38400 tty6
hendedav 2569 0.0 0.8 3552 1912 pts/1 Ss Oct24 0:00 -bash
root 2578 0.0 0.7 3044 1656 pts/1 S Oct24 0:00 bash
hendedav 3104 0.0 0.8 3560 1924 pts/0 Ss+ Oct24 0:00 -bash
root 6499 0.0 0.5 2704 1136 pts/1 S 13:45 0:00 /bin/
sh ./test.sh
root 6503 0.0 0.2 1876 460 pts/1 S 13:45 0:00 sleep 1
root 6504 0.0 0.3 2584 880 pts/1 R+ 13:45 0:00 ps au

I am trying to get the 6499 pid from the list. That is the actual pid
of the process that is being executed in the exec statment. Maybe I
didn't say things right in the first post, sorry.

Dave

 
Reply With Quote
 
Peter Makholm
Guest
Posts: n/a
 
      10-25-2007
(E-Mail Removed) writes:

> I switched the two lines of code as suggested, and I did get a print
> out, but it contained the same PID as the "my $pid=fork" statment.
> Here is the output:


Yes, of course. I wasn't actually reading what you wrote, just
noticed that you tried to write the pid out after the exec. 'use
warnings' should have warned you about that.

But ok, another (and better educated) guess about you problem:

'perldoc -f exec' says:

If there is more than one argument in LIST, or if LIST is an
array with more than one value, calls execvp(3) with the argu-
ments in LIST. If there is only one scalar argument or an
array with one element in it, the argument is checked for shell
metacharacters, and if there are any, the entire argument is
passed to the system's command shell for parsing (this is
"/bin/sh -c" on Unix platforms, but varies on other platforms).
If there are no shell metacharacters in the argument, it is
split into words and passed directly to "execvp", which is more
efficient. Examples:

exec('test.sh &') contains a shell metacharacter, namely '&', so what
exactly happens is

exec('/bin/sh', '-c', 'test.sh &');

You process (649 executes /bin/sh which tries to run test.sh in the
background and then exists. Running in the background means forking
another process.

The solution is not to pass the argument to the system shell:

exec('test.sh');

And you're allready (kind of) running the process in the background
after you have fork'ed.

//Makholm
 
Reply With Quote
 
hendedav@gmail.com
Guest
Posts: n/a
 
      10-25-2007
On Oct 25, 2:15 pm, Peter Makholm <(E-Mail Removed)> wrote:
> (E-Mail Removed) writes:
> > I switched the two lines of code as suggested, and I did get a print
> > out, but it contained the same PID as the "my $pid=fork" statment.
> > Here is the output:

>
> Yes, of course. I wasn't actually reading what you wrote, just
> noticed that you tried to write the pid out after the exec. 'use
> warnings' should have warned you about that.
>
> But ok, another (and better educated) guess about you problem:
>
> 'perldoc -f exec' says:
>
> If there is more than one argument in LIST, or if LIST is an
> array with more than one value, calls execvp(3) with the argu-
> ments in LIST. If there is only one scalar argument or an
> array with one element in it, the argument is checked for shell
> metacharacters, and if there are any, the entire argument is
> passed to the system's command shell for parsing (this is
> "/bin/sh -c" on Unix platforms, but varies on other platforms).
> If there are no shell metacharacters in the argument, it is
> split into words and passed directly to "execvp", which is more
> efficient. Examples:
>
> exec('test.sh &') contains a shell metacharacter, namely '&', so what
> exactly happens is
>
> exec('/bin/sh', '-c', 'test.sh &');
>
> You process (649 executes /bin/sh which tries to run test.sh in the
> background and then exists. Running in the background means forking
> another process.
>
> The solution is not to pass the argument to the system shell:
>
> exec('test.sh');
>
> And you're allready (kind of) running the process in the background
> after you have fork'ed.
>
> //Makholm



That makes sense. I have changed the code in the perl script and it
returns the correct pid!!! I read another post that said after
running the exec statment, it is a highly recommended to use an
"exit();" statement. Does this sound correct?

 
Reply With Quote
 
hendedav@gmail.com
Guest
Posts: n/a
 
      10-25-2007
On Oct 25, 2:32 pm, (E-Mail Removed) wrote:
> On Oct 25, 2:15 pm, Peter Makholm <(E-Mail Removed)> wrote:
>
>
>
> > (E-Mail Removed) writes:
> > > I switched the two lines of code as suggested, and I did get a print
> > > out, but it contained the same PID as the "my $pid=fork" statment.
> > > Here is the output:

>
> > Yes, of course. I wasn't actually reading what you wrote, just
> > noticed that you tried to write the pid out after the exec. 'use
> > warnings' should have warned you about that.

>
> > But ok, another (and better educated) guess about you problem:

>
> > 'perldoc -f exec' says:

>
> > If there is more than one argument in LIST, or if LIST is an
> > array with more than one value, calls execvp(3) with the argu-
> > ments in LIST. If there is only one scalar argument or an
> > array with one element in it, the argument is checked for shell
> > metacharacters, and if there are any, the entire argument is
> > passed to the system's command shell for parsing (this is
> > "/bin/sh -c" on Unix platforms, but varies on other platforms).
> > If there are no shell metacharacters in the argument, it is
> > split into words and passed directly to "execvp", which is more
> > efficient. Examples:

>
> > exec('test.sh &') contains a shell metacharacter, namely '&', so what
> > exactly happens is

>
> > exec('/bin/sh', '-c', 'test.sh &');

>
> > You process (649 executes /bin/sh which tries to run test.sh in the
> > background and then exists. Running in the background means forking
> > another process.

>
> > The solution is not to pass the argument to the system shell:

>
> > exec('test.sh');

>
> > And you're allready (kind of) running the process in the background
> > after you have fork'ed.

>
> > //Makholm

>
> That makes sense. I have changed the code in the perl script and it
> returns the correct pid!!! I read another post that said after
> running the exec statment, it is a highly recommended to use an
> "exit();" statement. Does this sound correct?



I have run into another problem. This code has been modified
(slightly) and inserted into a cgi script

if (defined (my $pid = fork)) {
if ($pid) {
local $SIG{CHLD} = "IGNORE";
print "Content-type: text/xml\n\n\n";
print "<info pid=\"". $pid ."\" date=\"".
scalar(localtime) ."\" />";
} else {
exec("/tmp/test.sh");
exit();
}
} else {
print "Content-type: text/xml\n\n\n";
print "<error>\n";
print "<message>The script couldn't be started.</message>\n";
print "</error>\n";
}

Now the webbrowser will not get a reply until the test.sh script has
finished executing. Any ideas?

Dave

 
Reply With Quote
 
hendedav@gmail.com
Guest
Posts: n/a
 
      10-25-2007
On Oct 25, 3:22 pm, Glenn Jackman <(E-Mail Removed)> wrote:
> At 2007-10-25 03:16PM, "(E-Mail Removed)" wrote:
> [...]
>
> > Now the webbrowser will not get a reply until the test.sh script has
> > finished executing. Any ideas?

>
> Your test.sh script should emit non-parsed headers:
> http://www.oreilly.com/openbook/cgi/ch03_08.html
>
> which means your perl script should probably be named "nph-whatever.pl"
> (depending on your web server).
>
> This is now off-topic for this group.
>
> --
> Glenn Jackman
> "You can only be young once. But you can always be immature." -- Dave Barry



I renamed the script and implemented the header suggested on that
link, but it still is not working. Can you suggest a group to post in
for this problem?

Thanks,
Dave

 
Reply With Quote
 
Gary E. Ansok
Guest
Posts: n/a
 
      10-25-2007
In article <(E-Mail Removed) m>,
<(E-Mail Removed)> wrote:
>I have run into another problem. This code has been modified
>(slightly) and inserted into a cgi script
>
>if (defined (my $pid = fork)) {
> if ($pid) {
> local $SIG{CHLD} = "IGNORE";
> print "Content-type: text/xml\n\n\n";
> print "<info pid=\"". $pid ."\" date=\"".
>scalar(localtime) ."\" />";
> } else {
> exec("/tmp/test.sh");
> exit();
> }
>} else {
> print "Content-type: text/xml\n\n\n";
> print "<error>\n";
> print "<message>The script couldn't be started.</message>\n";
> print "</error>\n";
>}
>
>Now the webbrowser will not get a reply until the test.sh script has
>finished executing. Any ideas?


One possibility is that the server is waiting for the output to be
completed before sending it off to the browser. The server won't
see end-of-file on the read end of the internal connection (between
the server and the cgi script) until all the processes have closed
the write end.

In this case, the process running /tmp/test.sh still has its standard
output set to that connection, so the server still needs to wait in
case test.sh writes more data.

The solution is to redirect standard output to a more suitable place
(or discard it by using /dev/null):

> } else {

open STDOUT, '>', '/dev/null';
> exec("/tmp/test.sh");
> exit();
> }


(Normally, we'd check to see if the open succeeded, but in this case
we presumably don't care as long as the existing channel gets closed.)

I would also close or re-direct STDIN and STDERR, unless you have
a reason not to.

Gary
--
The recipe says "toss lightly," but I suppose that depends
on how much you eat and how bad the cramps get. - J. Lileks
 
Reply With Quote
 
hendedav@gmail.com
Guest
Posts: n/a
 
      10-25-2007
On Oct 25, 4:12 pm, (E-Mail Removed) (Gary E. Ansok) wrote:
> In article <(E-Mail Removed) m>,
>
>
>
> <(E-Mail Removed)> wrote:
> >I have run into another problem. This code has been modified
> >(slightly) and inserted into a cgi script

>
> >if (defined (my $pid = fork)) {
> > if ($pid) {
> > local $SIG{CHLD} = "IGNORE";
> > print "Content-type: text/xml\n\n\n";
> > print "<info pid=\"". $pid ."\" date=\"".
> >scalar(localtime) ."\" />";
> > } else {
> > exec("/tmp/test.sh");
> > exit();
> > }
> >} else {
> > print "Content-type: text/xml\n\n\n";
> > print "<error>\n";
> > print "<message>The script couldn't be started.</message>\n";
> > print "</error>\n";
> >}

>
> >Now the webbrowser will not get a reply until the test.sh script has
> >finished executing. Any ideas?

>
> One possibility is that the server is waiting for the output to be
> completed before sending it off to the browser. The server won't
> see end-of-file on the read end of the internal connection (between
> the server and the cgi script) until all the processes have closed
> the write end.
>
> In this case, the process running /tmp/test.sh still has its standard
> output set to that connection, so the server still needs to wait in
> case test.sh writes more data.
>
> The solution is to redirect standard output to a more suitable place
> (or discard it by using /dev/null):
>
> > } else {

>
> open STDOUT, '>', '/dev/null';
>
> > exec("/tmp/test.sh");
> > exit();
> > }

>
> (Normally, we'd check to see if the open succeeded, but in this case
> we presumably don't care as long as the existing channel gets closed.)
>
> I would also close or re-direct STDIN and STDERR, unless you have
> a reason not to.
>
> Gary
> --
> The recipe says "toss lightly," but I suppose that depends
> on how much you eat and how bad the cramps get. - J. Lileks



Thanks for the help Gary. I inserted the redirect for STDOUT and also
tried STDIN (not sure how to with STDERR if the arrows are any
indication). I have also tried in on the commandline. here is what I
have tried:

} else {
open STDOUT, '>', '/dev/null';
open STDIN, '<', '/dev/null';
#open STDERR, '?', '/dev/null';
exec("/tmp/test.sh </dev/null >>/dev/null 2>&1");
}

Still no luck. Any other ideas or corrections in the code to try?

Dave

 
Reply With Quote
 
nolo contendere
Guest
Posts: n/a
 
      10-25-2007
On Oct 25, 4:40 pm, (E-Mail Removed) wrote:
> On Oct 25, 4:12 pm, (E-Mail Removed) (Gary E. Ansok) wrote:
>
>
>
> > In article <(E-Mail Removed) m>,

>
> > <(E-Mail Removed)> wrote:
> > >I have run into another problem. This code has been modified
> > >(slightly) and inserted into a cgi script

>
> > >if (defined (my $pid = fork)) {
> > > if ($pid) {
> > > local $SIG{CHLD} = "IGNORE";
> > > print "Content-type: text/xml\n\n\n";
> > > print "<info pid=\"". $pid ."\" date=\"".
> > >scalar(localtime) ."\" />";
> > > } else {
> > > exec("/tmp/test.sh");
> > > exit();
> > > }
> > >} else {
> > > print "Content-type: text/xml\n\n\n";
> > > print "<error>\n";
> > > print "<message>The script couldn't be started.</message>\n";
> > > print "</error>\n";
> > >}

>
> > >Now the webbrowser will not get a reply until the test.sh script has
> > >finished executing. Any ideas?

>
> > One possibility is that the server is waiting for the output to be
> > completed before sending it off to the browser. The server won't
> > see end-of-file on the read end of the internal connection (between
> > the server and the cgi script) until all the processes have closed
> > the write end.

>
> > In this case, the process running /tmp/test.sh still has its standard
> > output set to that connection, so the server still needs to wait in
> > case test.sh writes more data.

>
> > The solution is to redirect standard output to a more suitable place
> > (or discard it by using /dev/null):

>
> > > } else {

>
> > open STDOUT, '>', '/dev/null';

>
> > > exec("/tmp/test.sh");
> > > exit();
> > > }

>
> > (Normally, we'd check to see if the open succeeded, but in this case
> > we presumably don't care as long as the existing channel gets closed.)

>
> > I would also close or re-direct STDIN and STDERR, unless you have
> > a reason not to.

>
> > Gary
> > --
> > The recipe says "toss lightly," but I suppose that depends
> > on how much you eat and how bad the cramps get. - J. Lileks

>
> Thanks for the help Gary. I inserted the redirect for STDOUT and also
> tried STDIN (not sure how to with STDERR if the arrows are any
> indication). I have also tried in on the commandline. here is what I
> have tried:
>
> } else {
>
> open STDOUT, '>', '/dev/null';
> open STDIN, '<', '/dev/null';
> #open STDERR, '?', '/dev/null';
> exec("/tmp/test.sh </dev/null >>/dev/null 2>&1");
>
> }
>
> Still no luck. Any other ideas or corrections in the code to try?
>
> Dave



maybe autoflush?
$|++;

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
PID of exec hendedav@gmail.com Perl Misc 0 10-25-2007 05:18 PM
Runtime.exec(String[]) Doesn't Always Work, bBut Runtime.exec(String) Does Hal Vaughan Java 11 05-22-2006 04:49 PM
exec "statement" VS. exec "statement in globals(), locals() Ted Python 1 07-22-2004 08:51 AM
exec "statement" VS. exec "statement" in globals(), locals() tedsuzman Python 2 07-21-2004 08:41 PM
Backup Exec 9.1: The Backup Exec job engine system service is not responding Christian Falch Computer Support 1 06-23-2004 02:22 AM



Advertisments