in reply to Background process using a system call

I don't think you can use waitpid in conjunction with system in that way. Try doing something like this instead:
my @pids; foreach my $wks (@wkslist) { my $pid = fork; if ($pid == 0) { # child print "rshing to $wks \n"; system("$rsh_cmd $wks ls"); exit; } else { push(@pids,$pid); } } foreach my $pid (@pids) { waitpid($pid,0); }
The child that you forked (which you now have the pid of) will terminate when your system command does, thus emulating the behavior you're looking for.

/\/\averick
perl -l -e "eval pack('h*','072796e6470272f2c5f2c5166756279636b672');"

Replies are listed 'Best First'.
Re: Re: Background process using a system call
by mugwumpjism (Hermit) on Aug 21, 2001 at 04:45 UTC

    You've got the parent/child comments the wrong way round, you may as well use exec instead of the system/exit pair, and why not catch all of those return codes from rsh?

    local (%rc, $running); # turn off stdout buffering $| = 1; # catch return codes local $SIG{CHLD} = sub { $rc{wait()} = $?; --$running; }; foreach my $wks (@wkslist) { if ( my $pid = fork() ) { # parent ++$running; } else { # child print "rshing to $wks\n"; exec($rsh_cmd, $wks, "ls"); } } sleep while ($running);

    I have an old snippet which you may find useful at Run some commands in parallel

    Are you writing a program to execute arbitrary commands on multiple hosts at the same time? If so, check back in a day or two and I'll have the script I use posted that packs in a few features.

      ummm...according to "perldoc perlfunc" my parent/child comments aren't backwards.

      Fork Does a fork(2) system call to create a new process running the same program at the same point. It returns the child pid to the parent process, `0' to the child process, or `undef' if the fork is unsuc­cessful.

      In your code example you have

      if (my $pid = fork()) { # a true or non-zero value for the parent # stuff } else { # a false value or 0 for the child # stuff }
      Your logic is the same as mine.

      I used system because that is what he was using, it makes it clearer (at least to me) how his example correlated to my solution. I also tend to leave out the extra error checking because it can cause one to miss the point of the example...and by that token, you're not checking to see if your fork failed. :)

      To error test everything I guess the code would look like

      foreach my $wks (@wkslist) { my $pid = fork; if (!defined($pid)) { die "fork failed: $!"; } elsif ($pid == 0) { # child print "rshing to $wks\n"; exec("$rsh_cmd $wks ls") || die "exec failed for $wks: $!"; } else { push(@pids,$pid); } } foreach my $pid (@pids) { waitpid($pid,0); if ($? != 0) { print "non zero exit from $pid: $?"; } }
      give me a bit and I'll figure out how to make $? look pretty :)

      /\/\averick
      perl -l -e "eval pack('h*','072796e6470272f2c5f2c5166756279636b672');"