package Sys::uptime; use Class::Struct; use Carp; use strict; my $WAIT_CACHE = 5; struct 'Uptime' => [ 'uptime' => '$', 'users' => '$', 'load' => '%', 'as_string' => '$', ]; sub TIESCALAR { my $class = shift; my $self = { up => new Uptime, last_update => 0 }; bless $self, $class; $self; } sub FETCH { my $self = shift; if (time - $self->{last_update} > $WAIT_CACHE) { $self->{last_update} = time; my($str, $upt, $users, $one, $five, $fifteen) = get_uptime(); my $up = $self->{up}; $up->as_string($str); $up->uptime($upt); $up->users($users); $up->load('one', $one); $up->load('five', $five); $up->load('fifteen', $fifteen); } return $self->{up}; } sub get_uptime { local $_ = `uptime`; chomp; if (/^\s+\S+\s+ # opening cruft up\s+(.+?,?.+?), # uptime \s+(\d+)\s+users?, # number of users \s+load\s+averages?:\s+ # load average... (.+?),\s+(.+?),\s+(.+?)\s* # ...and values $/x) { return($_, $1, $2, $3, $4, $5); } else { croak "What was that? Bad uptime."; } } 1;