PID of exec

Discussion in 'Perl Misc' started by hendedav@gmail.com, Oct 25, 2007.

  1. Guest

    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";
    }
    , Oct 25, 2007
    #1
    1. Advertising

  2. 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
    Peter Makholm, Oct 25, 2007
    #2
    1. Advertising

  3. Guest

    On Oct 25, 1:33 pm, Peter Makholm <> wrote:
    > 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
    , Oct 25, 2007
    #3
  4. 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 (6498) 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
    Peter Makholm, Oct 25, 2007
    #4
  5. Guest

    On Oct 25, 2:15 pm, Peter Makholm <> wrote:
    > 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 (6498) 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?
    , Oct 25, 2007
    #5
  6. Guest

    On Oct 25, 2:32 pm, wrote:
    > On Oct 25, 2:15 pm, Peter Makholm <> wrote:
    >
    >
    >
    > > 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 (6498) 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
    , Oct 25, 2007
    #6
  7. Guest

    On Oct 25, 3:22 pm, Glenn Jackman <> wrote:
    > At 2007-10-25 03:16PM, "" 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
    , Oct 25, 2007
    #7
  8. In article <>,
    <> 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
    Gary E. Ansok, Oct 25, 2007
    #8
  9. Guest

    On Oct 25, 4:12 pm, (Gary E. Ansok) wrote:
    > In article <>,
    >
    >
    >
    > <> 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
    , Oct 25, 2007
    #9
  10. On Oct 25, 4:40 pm, wrote:
    > On Oct 25, 4:12 pm, (Gary E. Ansok) wrote:
    >
    >
    >
    > > In article <>,

    >
    > > <> 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?
    $|++;
    nolo contendere, Oct 25, 2007
    #10
  11. Guest

    On Oct 25, 6:09 pm, nolo contendere <> wrote:
    > On Oct 25, 4:40 pm, wrote:
    >
    >
    >
    > > On Oct 25, 4:12 pm, (Gary E. Ansok) wrote:

    >
    > > > In article <>,

    >
    > > > <> 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?
    > $|++;



    That seemed to have worked. Here is the adjusted code:

    } else {
    $|++;
    open STDOUT, '>', '/dev/null';
    open STDIN, '>', '/dev/null';
    open STDERR, '>', '/dev/null';
    exec("/tmp/test.sh");
    exit();
    }


    Does this look okay or do I need to add anything else?

    Thanks,
    Dave
    , Oct 25, 2007
    #11
  12. In article <>,
    <> wrote:
    [much snippage]
    >That seemed to have worked. Here is the adjusted code:
    >
    >} else {
    > $|++;
    > open STDOUT, '>', '/dev/null';
    > open STDIN, '>', '/dev/null';
    > open STDERR, '>', '/dev/null';
    > exec("/tmp/test.sh");
    > exit();
    >}


    STDIN should be opened with '<' rather than '>'. This won't matter
    unless /tmp/test.sh or something it calls tries to read from standard
    input, but if it does, better to get end-of-file instead of a
    runtime error.

    Gar
    Gary E. Ansok, Oct 26, 2007
    #12
  13. Guest

    On Oct 25, 7:49 pm, (Gary E. Ansok) wrote:
    > In article <>, <> wrote:
    >
    > [much snippage]
    >
    > >That seemed to have worked. Here is the adjusted code:

    >
    > >} else {
    > > $|++;
    > > open STDOUT, '>', '/dev/null';
    > > open STDIN, '>', '/dev/null';
    > > open STDERR, '>', '/dev/null';
    > > exec("/tmp/test.sh");
    > > exit();
    > >}

    >
    > STDIN should be opened with '<' rather than '>'. This won't matter
    > unless /tmp/test.sh or something it calls tries to read from standard
    > input, but if it does, better to get end-of-file instead of a
    > runtime error.
    >
    > Gar



    Thanks Gary. Is the STDERR pointed the correct way? Also, this
    script seems to be generating zombies. Anyone have ideas on how to
    clear that up? I was hoping that the "local $SIG{CHLD} = "IGNORE";"
    line would do the trick (as it stated in the perldoc's), but I guess
    not.

    Thanks,
    Dave
    , Oct 26, 2007
    #13
  14. J. Gleixner Guest

    wrote:

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


    > Thanks Gary. Is the STDERR pointed the correct way?


    Well, does the program possibly read or does it
    possibly write? You should know the difference
    between '<', and '>', long before you ever use
    fork(), IMHO.
    J. Gleixner, Oct 26, 2007
    #14
  15. Guest

    wrote:

    > Also, this
    > script seems to be generating zombies. Anyone have ideas on how to
    > clear that up?


    You could double-fork.

    > I was hoping that the "local $SIG{CHLD} = "IGNORE";"
    > line would do the trick (as it stated in the perldoc's), but I guess
    > not.


    What if the "local" expires before the child does? Then IGNORE is no
    longer in effect and you leave zombies. Did the docs say to set $SIG{CHLD}
    to IGNORE with local? That seems like a manifestly bizarre thing to do.
    The effects of $SIG{CHLD} are inherently global and pretending it can be
    localized is going to get you no where fast.

    Xho

    --
    -------------------- http://NewsReader.Com/ --------------------
    The costs of publication of this article were defrayed in part by the
    payment of page charges. This article must therefore be hereby marked
    advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate
    this fact.
    , Oct 26, 2007
    #15
  16. Guest

    On Oct 26, 11:30 am, "J. Gleixner" <glex_no-s...@qwest-spam-
    no.invalid> wrote:
    > wrote:
    > >>> open STDOUT, '>', '/dev/null';
    > >>> open STDIN, '>', '/dev/null';
    > >>> open STDERR, '>', '/dev/null';

    > > Thanks Gary. Is the STDERR pointed the correct way?

    >
    > Well, does the program possibly read or does it
    > possibly write? You should know the difference
    > between '<', and '>', long before you ever use
    > fork(), IMHO.


    Thanks for the reply J, but I was unfamiliar with the usage in perl.
    Redirecting in bash uses the same arrow (eg 2>&1). Plus, you run out
    of arrows after STDIN and STDOUT, so I had no idea what to use for
    STDERR. So, I figured maybe they all used the same arrow. Oh well...

    Dave
    , Oct 26, 2007
    #16
  17. Guest

    On Oct 26, 12:29 pm, wrote:
    > wrote:
    > > Also, this
    > > script seems to be generating zombies. Anyone have ideas on how to
    > > clear that up?

    >
    > You could double-fork.
    >
    > > I was hoping that the "local $SIG{CHLD} = "IGNORE";"
    > > line would do the trick (as it stated in the perldoc's), but I guess
    > > not.

    >
    > What if the "local" expires before the child does? Then IGNORE is no
    > longer in effect and you leave zombies. Did the docs say to set $SIG{CHLD}
    > to IGNORE with local? That seems like a manifestly bizarre thing to do.
    > The effects of $SIG{CHLD} are inherently global and pretending it can be
    > localized is going to get you no where fast.
    >
    > Xho
    >
    > --
    > --------------------http://NewsReader.Com/--------------------
    > The costs of publication of this article were defrayed in part by the
    > payment of page charges. This article must therefore be hereby marked
    > advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate
    > this fact.



    No I don't recall the doc's saying to use local, but while working
    with another part of the project, I was searching for answers and come
    upon that as a solution. Anyhow, I removed the 'local' portion, but I
    am still receiving zombies. I will post the entire script now for
    review:


    #!/usr/bin/perl -w

    use strict;
    use CGI qw:)all);
    use CGI::Carp qw(fatalsToBrowser);

    if (defined param('runnow')) {
    if (defined (my $pid = fork)) {
    if ($pid) {
    $SIG{CHLD} = "IGNORE";
    print "Content-type: text/xml", "\n\n";
    print "<info pid=\"". $pid ."\" date=
    \"".scalar(localtime)."\" />";
    } else {
    $|++;
    open STDOUT, '>', '/dev/null';
    open STDIN, '<', '/dev/null';
    open STDERR, '>', '/dev/null';
    $_ = param('runnow');
    exec("/tmp/test.sh");
    exit();
    }
    } else {
    print "Content-type: text/xml", "\n\n";
    print "<error>\n";
    print "<message>The script couldn't be started.</message>\n";
    print "</error>\n";
    }

    } elsif (defined param('pollJob')) {
    my $pid = param('pollJob');
    my $retval = `ps h -p $pid 2>&1`;

    print "Content-type: text/plain", "\n\n";
    if ($retval eq "") {
    print "Restore job completed...";
    } else {
    open(REJ, "/tmp/rej$pid");
    chomp ($retval=<REJ>);
    close(REJ);
    if ($retval ne 'Processing select data...') {
    print "$retval";
    } else {
    my $dir = readlink "/tmp/rej$pid.data";
    $dir = "/mnt" . substr($dir, rindex($dir,"/"), -4);
    my $data = '';
    if (! open(FILES, "/tmp/rej$pid.data")) { exit 0; }
    while (<FILES>) {
    s/^\./$dir/;
    if (-e $_) {$data .= "$_<br />";} else {last;}
    }
    close(FILES);
    print $data;
    }
    }
    }


    The top if statement only gets executed once (to start a process which
    is monitored by the pollJob section), then the pollJob gets called
    between 2-3 seconds until the job is done. This job is only running
    for 30 seconds (because of the test.sh script), but I accumulate
    several many zombies. Any ideas?

    Thanks
    Dave
    , Oct 26, 2007
    #17
  18. wrote in news:1193419373.121190.211760
    @v3g2000hsg.googlegroups.com:

    > On Oct 26, 11:30 am, "J. Gleixner" <glex_no-s...@qwest-spam-
    > no.invalid> wrote:
    >> wrote:
    >> >>> open STDOUT, '>', '/dev/null';
    >> >>> open STDIN, '>', '/dev/null';
    >> >>> open STDERR, '>', '/dev/null';
    >> > Thanks Gary. Is the STDERR pointed the correct way?

    >>
    >> Well, does the program possibly read or does it
    >> possibly write? You should know the difference
    >> between '<', and '>', long before you ever use
    >> fork(), IMHO.

    >
    > Thanks for the reply J, but I was unfamiliar with the usage in perl.
    > Redirecting in bash uses the same arrow (eg 2>&1). Plus, you run out
    > of arrows after STDIN and STDOUT, so I had no idea what to use for
    > STDERR. So, I figured maybe they all used the same arrow. Oh well...


    This is a WTF in so many ways.

    1) 2 > &1 means redirect the stderr output to where stdout points.

    2) The pointy edge of the angle bracket is the target. So:

    open FILEHANDLE, '<', 'source'

    means you want to use FILEHANDLE to read from 'source'. On the other
    hand,

    open ANOTHERHANDLE, '>', 'target'

    means you want to write to 'target' the output you send to
    ANOTHERHANDLE.

    STDERR is an output stream just as STDOUT is. STDIN is an input stream.
    I would think the suffixes OUT and IN would give that away. Now, I
    think, it is common sense (I have not questioned this in the last 20
    years) that STDERR is the stream where you *output* error messages so,
    again, the pointy edge of the angle bracket points away from the STDERR
    and to the target of that stream.

    "I was running out of arrows so I used the same one for all of them".
    This is not a grocery store: The logic of "they had run out of apples so
    I bought pears" cannot be applied.

    I think I am scarred for life (again).

    Sinan

    --
    A. Sinan Unur <>
    (remove .invalid and reverse each component for email address)
    clpmisc guidelines: <URL:http://www.augustmail.com/~tadmc/clpmisc.shtml>
    A. Sinan Unur, Oct 26, 2007
    #18
  19. Guest

    wrote:
    > On Oct 26, 12:29 pm, wrote:
    > > wrote:
    > > > Also, this
    > > > script seems to be generating zombies. Anyone have ideas on how to
    > > > clear that up?

    > >
    > > You could double-fork.
    > >
    > > > I was hoping that the "local $SIG{CHLD} = "IGNORE";"
    > > > line would do the trick (as it stated in the perldoc's), but I guess
    > > > not.

    > >
    > > What if the "local" expires before the child does? Then IGNORE is no
    > > longer in effect and you leave zombies. Did the docs say to set
    > > $SIG{CHLD} to IGNORE with local? That seems like a manifestly bizarre
    > > thing to do. The effects of $SIG{CHLD} are inherently global and
    > > pretending it can be localized is going to get you no where fast.
    > >

    >
    > No I don't recall the doc's saying to use local, but while working
    > with another part of the project, I was searching for answers and come
    > upon that as a solution. Anyhow, I removed the 'local' portion, but I
    > am still receiving zombies. I will post the entire script now for
    > review:


    First, are the zombies something to worry about? If they go away by
    soon enough so they don't clog up the kernel anyway, don't worry about
    them.


    .....
    >
    > The top if statement only gets executed once (to start a process which
    > is monitored by the pollJob section), then the pollJob gets called
    > between 2-3 seconds until the job is done. This job is only running
    > for 30 seconds (because of the test.sh script), but I accumulate
    > several many zombies. Any ideas?


    Since the code you show only forks once and is only run once, it couldn't
    give rise to many zombies. The zombies must be coming from someplace else.

    Xho

    --
    -------------------- http://NewsReader.Com/ --------------------
    The costs of publication of this article were defrayed in part by the
    payment of page charges. This article must therefore be hereby marked
    advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate
    this fact.
    , Oct 26, 2007
    #19
  20. Guest

    On Oct 26, 2:32 pm, wrote:
    > wrote:
    > > On Oct 26, 12:29 pm, wrote:
    > > > wrote:
    > > > > Also, this
    > > > > script seems to be generating zombies. Anyone have ideas on how to
    > > > > clear that up?

    >
    > > > You could double-fork.

    >
    > > > > I was hoping that the "local $SIG{CHLD} = "IGNORE";"
    > > > > line would do the trick (as it stated in the perldoc's), but I guess
    > > > > not.

    >
    > > > What if the "local" expires before the child does? Then IGNORE is no
    > > > longer in effect and you leave zombies. Did the docs say to set
    > > > $SIG{CHLD} to IGNORE with local? That seems like a manifestly bizarre
    > > > thing to do. The effects of $SIG{CHLD} are inherently global and
    > > > pretending it can be localized is going to get you no where fast.

    >
    > > No I don't recall the doc's saying to use local, but while working
    > > with another part of the project, I was searching for answers and come
    > > upon that as a solution. Anyhow, I removed the 'local' portion, but I
    > > am still receiving zombies. I will post the entire script now for
    > > review:

    >
    > First, are the zombies something to worry about? If they go away by
    > soon enough so they don't clog up the kernel anyway, don't worry about
    > them.
    >
    > ....
    >
    >
    >
    > > The top if statement only gets executed once (to start a process which
    > > is monitored by the pollJob section), then the pollJob gets called
    > > between 2-3 seconds until the job is done. This job is only running
    > > for 30 seconds (because of the test.sh script), but I accumulate
    > > several many zombies. Any ideas?

    >
    > Since the code you show only forks once and is only run once, it couldn't
    > give rise to many zombies. The zombies must be coming from someplace else.
    >
    > Xho
    >
    > --
    > --------------------http://NewsReader.Com/--------------------
    > The costs of publication of this article were defrayed in part by the
    > payment of page charges. This article must therefore be hereby marked
    > advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate
    > this fact.



    The reason that I know that they come from this script is because it
    is the only file with its name shown in the ps listing with a
    "<defunct>" statement beside each occurance. I end up with about 4 or
    5 zombies (that I have paid attention to) for just the 30 seconds of
    the test.sh script, but what if the script runs for minutes or hours?
    The script shown isn't run just once, it is run every 2-3 seconds
    until the test.sh script (which will eventually be replaced with
    another script that performs an actual job) is completed.

    Dave
    , Oct 26, 2007
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Hal Vaughan
    Replies:
    11
    Views:
    1,090
    Gordon Beaton
    May 22, 2006
  2. tedsuzman
    Replies:
    2
    Views:
    7,062
    Michel Claveau, résurectionné d'outre-bombe inform
    Jul 21, 2004
  3. Ted
    Replies:
    1
    Views:
    451
    Duncan Booth
    Jul 22, 2004
  4. Guillermo Riojas
    Replies:
    0
    Views:
    156
    Guillermo Riojas
    Nov 26, 2010
  5. PID of exec

    , Oct 25, 2007, in forum: Perl Misc
    Replies:
    0
    Views:
    81
Loading...

Share This Page