Home > Software design >  Perl: How to get the PID of the command executed using "make"
Perl: How to get the PID of the command executed using "make"

Time:07-26

I have a Perl script, and in that script, I am executing the "make" command over the list of test cases. Now, I want to have the PID of each "make" command when it runs the test case so that I can monitor those PIDs.

Let's say, I have a test list @array1 = ("/home/abc/test1/makefile", "/home/bcd/qwe/test2/makefile", "/home/PPP/makefile"). Now, when I run "make" on "/home/abc/test1/makefile", I need the unique PID of this command (make /home/abc/test1/makefile). Then, when I run "make" on "/home/bcd/qwe/test2/makefile", I must get another unique ID, and similarly for other tests.

I would then use each PID to monitor for their time i.e. if a certain test executed using make (with a unique ID) reaches a time limit, then I would do something (that will be done via fork), but for that monitoring to happen, I would need the PIDs.

Code Snippet which I am using:

foreach my $i (@array1)
{
   my $filehandle;
   if ( ! open( $filehandle, "make $i 2>&1 |" ) ) {
       die( "Failed to start process: $!" );
   }
   else {
       print "Test started\n";
   }
   while ( defined( my $line = <$filehandle> ) ) {
       print( $line );
   }
}

How can I get the PIDs?

CodePudding user response:

The pid of make is returned by open. perldoc -f open states:

        Open returns nonzero on success, the undefined value otherwise.
        If the "open" involved a pipe, the return value happens to be
        the pid of the subprocess.

Getting the pid of processes spawned by make is a different question, and will require more effort.

CodePudding user response:

open returns the PID of the process it creates. But the process being created is running sh. The PID you should receive is the PID of the shell you're launching, not that of make.[1]

If you weren't trying to execute a shell command, you could use the "list form" of open to avoid the shell. But that's not available to you since you want to use the shell to perform redirection.

There are ways to address this will still using open -|, but it's far simpler to use IPC::Run, and it handles the timeout trivially.

use IPC::Run qw( run timeout );

run [ "make", $i ],
   ">",  \my $stdout,   # Or whatever
   "2>", \my $stderr,   # Or whatever
   timeout( 10 );

die( "make killed by signal ".( $? & 0x7F )."\n" ) if $? & 0x7F;
die( "make exited with error ".( $? >> 8 )."\n" ) if $? >> 8;

say "make successful.";

  1. Perl sometimes optimizes the use of the shell away.
  • Related