Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

Re^2: forking and monitoring processes

by Anonymous Monk
on Jan 08, 2005 at 17:48 UTC ( [id://420552]=note: print w/replies, xml ) Need Help??


in reply to Re: forking and monitoring processes
in thread forking and monitoring processes

Hello,

Thanks for the response, it makes things a lot clearer. A few questions I had was:

my $pid = open my $fh, "-|", $_

This means pipe open the process to the filehandler right? I wasn't sure what the "-" in " -|" meant.

Also, after looking at each line, I would like to store the output of each child process into different files. So for process 1, I want to store the output into proc1.txt etc. But when processing each line, I am only aware of the pid and not the process running so I was wondering how I can write to the file proc1.txt if I only know proc1's pid is running and so on?

Thanks.

Replies are listed 'Best First'.
Re^3: forking and monitoring processes
by revdiablo (Prior) on Jan 08, 2005 at 19:39 UTC
    But when processing each line, I am only aware of the pid and not the process running

    That's why I changed to a hash of arrays to store the PIDs and process information. You can get the program name by $pid{$fh}[1], or put more information into that array as necessary.

    Update: your question about -| can be fully answered by reading open's documentation. The short answer is it opens a process for reading.

      Hello,

      Thanks for reply. When I run the program, the processes seems to start but the program seems to timeout at the select command can_read. Since it a dir command, output is expected immediatly, I was not sure why it was timing out.

      #! perl use IO::Select; my %pids; my $s = IO::Select->new(); my @proc = (qw(C M)); for ( <@proc> ) { my $cmd = "dir $_:"; print "this is my cmd: $cmd \n\n"; my $pid = open my $fh, "-|", $cmd or warn "Could not fork&open $cmd: $!" and next; $pids{$fh} = [ $pid, $_ ]; $s->add($fh); } while (my @ready = $s->can_read) { for my $fh (@ready) { if (eof $fh) { delete $pids{$fh}; $s->remove($fh); next; } my $line = <$fh>; if ($line =~ /Rational/) { chomp $line; print "Found 'Rational' in '$line' from $pid{$fh}[1]\n"; kill 15, values %pids; } } }

      Thanks.

        There are a few problems here. The first is that by iterating on <@proc>, you're using glob to iterate on an array. It works in this case, but should not be used for that purpose. Instead, you should simply use:

        for (@proc) {

        The next, more critical problem, is in this code:

        my $cmd = "dir $_:"; my $pid = open my $fh, "-|", $cmd # ...

        As the open docs state, this form of open does not pass the command through the shell, but rather executes it directly. The shell is where word splitting (e.g. "dir C:" to "dir", "C:") normally happens, but that won't happen here. That means you are attempting to execute a program called "dir C:". As you can imagine, you probably do not have that program on your system.

        Most of the time, the solution is to do something like this:

        my $pid = open my $fh, "-|", "dir", "$_:" # ...

        But in this case, you probably don't have a program named "dir" either. I might be wrong, but I think dir is built in to Win32's shell, cmd.exe. So you have two options. Either you can continue to use the same form of open, and call the shell yourself, or use the form of open that executes commands through the shell anyway. In this case, I would probably opt for the latter, for simplicity:

        my $pid = open my $fh, "dir $_: |" # ...

        The last problem in your code is my fault. It's a bug I fixed, but apparently you grabbed the code before I did so. This line:

        kill 15, values %pids;

        Should be changed to:

        kill 15, map {$_->[0]} values %pids;

        PS: If reading files in certain directories is your end goal, you might be able to accomplish it more easily with Perl builtins, such as readdir or glob, instead of shelling out to dir. But hopefully you will have learned something in the process. :-)

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://420552]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chanting in the Monastery: (5)
As of 2025-06-13 10:02 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?
    erzuuliAnonymous Monks are no longer allowed to use Super Search, due to an excessive use of this resource by robots.