klik_66 has asked for the wisdom of the Perl Monks concerning the following question:

What I am trying to do is read log files from several different servers. In the ksh script I am replacing I use __remsh HOST cat /log/file.name > HOST.log.TIME.tmp & __. I then wait for the command to finish on all HOSTs. Then I sort the info, make it presentable, etc. The last thing I do is remove all the tmp files.

Using perl, it seems to me, I should be able to open a pipe to the command and store the log file without writing the temp file.

Two questions: 1. How can I get the reading of all the logfiles to happen at the same time (like the shell &) 2. How can I store the log info so I can get at it by HOST name. For example, a hash with keys being HOST1, HOST2... and the values being the log file contents.

thanks

  • Comment on Reading input from concurrent processes

Replies are listed 'Best First'.
Re: Reading input from concurrent processes
by chromatic (Archbishop) on May 20, 2000 at 04:53 UTC
    Unless you do some tricky shared memory manipulation (IPC::SysV on CPAN), using fork to execute your remote shell commands won't let you avoid the temporary file thing. Either you can give up on simultaneous access, or on the temp files (as far as I can see).

    The piping thing certainly works. What I would do is something like this:

    • Make an array of host names
    • Loop through the array
    • Set an alarm to time out if the command doesn't finish within 30 seconds (or whatever)
    • Execute the remsh command
    • Store the hostname => remsh output in your hash
    • Reset the alarm to zero seconds
    • Do something or other with the hash
    The disclaimer, of course, is that I've only been programming in a Unix environment for a couple of years, so there may be a module or a technique that does this better.
Re: Reading input from concurrent processes
by floopy (Sexton) on May 20, 2000 at 13:20 UTC
    I'm not sure why you couldn't do something like

    $i=0;
    while ($i < NUMBEROF HOSTS) {
    $pid = fork();
    if ($pid == 0) {
    my $instance=$i;
    last;
    (etc.)

    and have some array w/ the hostnames and each child would use array$i for the hostname then do the pipe.
    Another possibility is to use anonymous typeglobs and generate a typeglob for each hostname and use it to open the process to pipe, etc. and test each filehandle to see if it is ready to be read (i.e. non-blocking I/O)...uggh.
    Sounds like there should be a CPAN module for this.
    The only real advantage to punk music is that nobody can whistle it.