既然你打开了一个管道,你需要从opening之前到至少读完之后的时间
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
或者,为了计时整个过程,在管道上调用close之后(在所有读取完成之后)
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 阻塞并等待程序完成
关闭管道还会等待在管道上执行的进程退出——以防你想在之后查看管道的输出——并将该命令的退出状态值隐式放入$? [。 ..]
有关状态检查,请参阅 $? variable in perlvar 和 system
如果定时程序分叉并且不以阻塞方式对其子级进行wait,这将无法正确计时。
在这种情况下,您需要识别他们使用的资源(文件?)并对其进行监控。
我想补充一点,外部命令应该小心组合在一起,以避免 shell 注入问题。一个好的模块是String::ShellQuote。参见例如this answer 和this answer
使用模块来捕获流可以让您从 shell 中解放出来,并且可能会打开其他方式来运行和更可靠地计时。一个好的是Capture::Tiny(还有其他的)。
感谢 HåkonHægland 提供 cmets。感谢ikegami 让我直截了当,使用close(而不是waitpid)。