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.";
- Perl sometimes optimizes the use of the shell away.