Measure program execution time with Perl "open"

I am working on a test suite library that uses Perl open

to run tests. It looks something like this:

open (MYOUT, "$myprog $arg1 $arg2 $arg3 2>&1 |") die "Bad stuff happened";

      

What I would really like to do is measure the execution time $myprog

. Unfortunately, simply grabbing the start and end times around the command open

just takes approximately the time it takes to start the process.

Is there a way to get the command open

to terminate the process (and therefore measure the time accurately), or perhaps something else to accomplish the same thing?

The key constraints are that we need to capture (possibly many) STDOUT

and STDERR

.

+3


source to share


1 answer


Since you open the tube you need time before open

ing, at least after reading

use warnings;
use strict;
use Time::HiRes qw(gettimeofday tv_interval sleep);

my $t0 = [gettimeofday];

open my $read, '-|', qw(ls -l) or die "Can't open process: $!";

while (<$read>)
{
    sleep 0.1;
    print;
}

print "It took ", tv_interval($t0), " seconds\n";
# close pipe and check 

      

or so that the time of the whole process, after the call close

on the pipe (after everything has been read)

my $t0 = [gettimeofday];
open my $read, '-|', qw(ls -l)  or die "Can't open process: $!";
# ... while ($read) { ... }
close $read  or 
    warn $! ? "Error closing pipe: $!" : "Exit status: $?";
print "It took ", tv_interval($t0), " seconds\n";

      

close blocks and waits for the program to finish

Closing the pipe also waits for the process running on the pipe to finish - in case you want to see the output after that - and implicitly puts the value of the exit status of this command in $?

[...]



To check the status see $? variable in perlvar and system

If a programmed program evolves and does not block wait

on its children, it will not result in their correct timing. In this case, you need to identify the resources they are using (files?) And keep track of that.

I would like to add that external commands should be carefully assembled to avoid corpus injection problems. Nice String :: ShellQuote module . See for example this answer and this answer

Using a module to capture threads will free you from the shell and possibly open up other ways to start and time to do this more reliably Nice Capture :: Tiny (and there are others).

Thanks to HรฅkonHรฆgland for the comments. Thanks to ikegami for setting me straight, use close

(not waitpid

).

+2


source







All Articles