Re: Bash: command output to variable



Steffen Schuler wrote:
------------------------- (top.pl) ---------------------------------
#!/usr/bin/env perl

# more optimal but less portable as first line:
#!/usr/bin/perl

# to quit the command you have to enter 'q' or 'Q'

# some pragmas to help error finding
use strict;
use warnings;
use diagnostics;


# perlvar: '-no_match_vars' is recommended for performance reasons
use English '-no_match_vars';

use POSIX 'strftime';

# should be installed from CPAN
use Term::ReadKey;

my $logfile = "toplog";
$English::OUTPUT_AUTOFLUSH = 1;
my $clear_string = `clear`;

open(TTY, "</dev/tty");
ReadMode "normal";

open(LOG, ">$logfile") or
die "can't open \"$logfile\": $!";

while (1) {
my $first_line = "\n";
print $clear_string;
if (open(PSOUT,
"ps -eao pcpu,pmem,comm --no-headers --sort=-pcpu |")) {
for (my $i = 0; $i < 10; ++$i) {
if (defined($_ = <PSOUT>)) {
print;
my ($F) = split;
print LOG strftime( '%T', localtime ), " $_" if $F >= 10.0;
}
}
} else {
die "can't open pipe from command: $!";
}

my $key = readKeyQuit(5);
if (defined($key) and $key =~ /q/i) {
exit 0;
}
}

close(PSOUT) or die "cant't close piped command: $!";
close(LOG) or die "can't close \"$logfile\": $!";
close(TTY) or die "can't close \"/dev/tty\": $!";


# reads key with a timeout of 5 seconds without echo
sub readKeyQuit
{
my $timeout = shift;
my $key = '';
eval {
# start alarm handler after $timeout seconds
local $SIG{ALRM} = sub { die "alarm clock restart" };
alarm $timeout;

ReadMode "raw";

# ReadKey 5, *TTY; doesn't seem to work
$key = ReadKey 0, *TTY;

ReadMode "normal";

# start alarm handler immediately
alarm 0;
};

# if the Perl syntax error message string exists and is not
# "alarm clock restart" then die
if ($EVAL_ERROR and $EVAL_ERROR !~ /alarm clock restart/) { die };

return $key;
}
---------------------- end(top.pl) -------------------------------

I didn't recognized that I exited without closing.
Better:

--------------------- begin(top.pl) ---------------------------
#!/usr/bin/env perl

# more optimal but less portable as first line:
#!/usr/bin/perl

# to quit the command you have to enter 'q' or 'Q'

# some pragmas to help error finding
use strict;
use warnings;
use diagnostics;


# perlvar: '-no_match_vars' is recommended for performance reasons
use English '-no_match_vars';

use POSIX 'strftime';

# should be installed from CPAN
use Term::ReadKey;

my $logfile = "toplog";
$English::OUTPUT_AUTOFLUSH = 1;
my $clear_string = `clear`;

open(TTY, "</dev/tty");
ReadMode "normal";

open(LOG, ">$logfile") or
die "can't open \"$logfile\": $!";

my $key;

do {
my $first_line = "\n";
print $clear_string;
if (open(PSOUT,
"ps -eao pcpu,pmem,comm --no-headers --sort=-pcpu |")) {
for (my $i = 0; $i < 10; ++$i) {
if (defined($_ = <PSOUT>)) {
print;
my ($F) = split;
print LOG strftime( '%T', localtime ), " $_" if $F >= 10.0;
}
}
} else {
die "can't open pipe from command: $!";
}

$key = readKeyQuit(5);

} until (defined($key) and $key =~ /q/i);

close(PSOUT) or die "cant't close piped command: $!";
close(LOG) or die "can't close \"$logfile\": $!";
close(TTY) or die "can't close \"/dev/tty\": $!";


# reads key with a timeout of 5 seconds without echo
sub readKeyQuit
{
my $timeout = shift;
my $key = '';
eval {
# start alarm handler after $timeout seconds
local $SIG{ALRM} = sub { die "alarm clock restart" };
alarm $timeout;

ReadMode "raw";

# ReadKey 5, *TTY; doesn't seem to work
$key = ReadKey 0, *TTY;

ReadMode "normal";

# start alarm handler immediately
alarm 0;
};

# if the Perl syntax error message string exists and is not
# "alarm clock restart" then die
if ($EVAL_ERROR and $EVAL_ERROR !~ /alarm clock restart/) { die };

return $key;
}
--------------------- end(top.pl) -----------------------------

Greetings from Munich,

Steffen
.



Relevant Pages

  • Re: Bash: command output to variable
    ... list top 10 cpu intensive processes. ... An optimized perl solution: ... # reads a key without echo and with a timeout of $timeout seconds ... alarm $timeout; ...
    (comp.unix.shell)
  • Re: Time out question
    ... There are quite a lot of problems with alarm() ... from time_limit import time_limit, TimeOut ... raise TimeOut() ... # Install new handler remembering old ...
    (comp.lang.python)
  • Re: How to time out a forked command but still see output?
    ... Haven't done Perl in years. ... I tried a few things involving alarm() and eval but couldn't get them ... I also tried something like redirecting CMD to STDOUT but when I do ... die "\nTimed out command $command after waiting ...
    (comp.lang.perl.misc)
  • Re: creating a socket connection timeout in "C" linux
    ... What makes alarm() unreliable? ... The 'easy, unreliable timeout' is setting ... the SIGALRM may actually be posted to the process before the connect ... Relying on SIGALRM to interrupt a blocked system call could ...
    (comp.unix.programmer)
  • Re: Cursor moving in one position
    ... On Mon, 9 Feb 2004, Ricardo Pichler wrote: ... I tested the following on RedHat Linux 9.0 using Perl 5.8.0. ... The alarm() function only has resolution to about 1 ... This means you can cancel your "spinner" using ...
    (perl.beginners)