DouglasDD has asked for the wisdom of the Perl Monks concerning the following question:
Longer Tale of Woe...
I've been working on a script that does some long-term monitoring of the health of a Linux box on one of our customer sites. (So that when we get a bug report that says "the system was really slow for a while last Tuesday after lunch", we'll have some data to look at).
The following 'top' command generates everything that I want to know about the "health" of the Linux box overall as well as the individual processes that we care to monitor:
top -bcS -n 1 -b batch mode (non-interactive) -n <num> iteration count -S cumulative CPU for dead children -c display full command line
Given,
...Hmm, it looks like `top` is trying to outsmart me because it knows that my terminal is only 80 characters wide (truncating the full command line that I requested with (-c)).lll.pl: sub longestLineLength { my $longestLen = undef; for my $l ( @_ ) { if ( length($l) > $longestLen ) { $longestLen = length($l); } } return $longestLen; } test-01.pl: #!/usr/bin/perl require "lll.pl"; open (TOP, "/usr/bin/top -bcS -n 1 |") || die "open pipe from top failed $!"; print longestLineLength( <TOP> ) . "\n"; $ ./test-01.pl 80
Alright, I can fool it:
Externally:
$ COLUMNS=1000 ./test-01.pl 552
OR Internally test-02.pl:
open (TOP, "COLUMNS=1000 /usr/bin/top -bcS -n 1 |") OR open (TOP, "/usr/bin/env -i COLUMNS=1000 /usr/bin/top -bcS -n 1 |" +)
And all is well:
$ ./test-02.pl 552
...once again 'top' is truncating all my command lines!$ ./test-02.pl 2>err 81
How can redirecting STDERR possibly relate to terminal width? I don't know, but it behaves the same whether the STDERR re-direct is externally (in the shell as above), or internally (in the perl script below):
...It doesn't seem to matter whether the destination of STDERR is a real file or /dev/null, the behavior is the same: truncated linestest-03.pl: open (TOP, "/usr/bin/env -i COLUMNS=1000 /usr/bin/top -bcS -n 1 2> +err.txt |") $ ./test-03.pl 81
so next I tried some funky stuff that I learned from 'perlopentut'...
test-04.pl:
...same result: any attempt at capturing STDERR results in trimmed lines! It doesn't seem to matter whether I use open() or IO::File, the result is exactly the same.#!/usr/bin/perl require "lll.pl"; my $outFileName = shift @ARGV; my $errFileName = $outFileName . ".err"; open( STDOUT, ">> $outFileName" ) || die "failed to redirect STDOUT to '$outFileName': $!"; open( STDERR, ">> $errFileName" ) || die "failed to redirect STDERR to '$errFileName': $!"; open (TOP, "/usr/bin/env -i COLUMNS=1000 /usr/bin/top -bcS -n 1 |" +) || die "open pipe from top failed $!"; print longestLineLength( <TOP> ) . "\n"; $ ./test-04.pl output $ cat output 81
By definition this script is a long-running process, I NEED to capture STDERR somehow, so that I can watch for the error conditions, 'warn's, etc.
I'm at the end of my rope, my next step is to re-write it and replace all occurances of 'warn', 'die', etc. with my own versions that write to a private file-handle (not STDERR). But in addition to being nasty, that's a problem because I'll be losing any STDERR output that is emitted by child processes ('top', etc)).
$ perl -v This is perl, v5.6.1 built for i386-linux $ type -a top top is /usr/bin/top $ rpm -qf /usr/bin/top procps-2.0.7-11 $ ls -l /bin/sh ... /bin/sh -> bash $ rpm -qf /bin/bash /bin/sh bash-2.05-8 bash-2.05-8 $ uname -a Linux ahost 2.4.9-e.40enterprise #1 SMP Thu Apr 8 16:43:01 EDT 2004 i6 +86 unknown (actually it's RedHat Enterprise Linux 2.1, w/ recent patches)
Pardon me for asking what might be a Linux question, but I'm hoping that the perl gurus will know of a away that I can work-around it with perl!
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: top and STDERR hell...
by Roy Johnson (Monsignor) on Jun 07, 2005 at 23:52 UTC | |
by DouglasDD (Beadle) on Jun 08, 2005 at 01:56 UTC | |
|
Re: top and STDERR hell...
by ikegami (Patriarch) on Jun 07, 2005 at 21:45 UTC | |
by Anonymous Monk on Jun 08, 2005 at 01:38 UTC | |
by DouglasDD (Beadle) on Jun 08, 2005 at 01:39 UTC | |
|
Re: top and STDERR hell...
by tlm (Prior) on Jun 08, 2005 at 01:47 UTC | |
by DouglasDD (Beadle) on Jun 08, 2005 at 02:07 UTC | |
by tlm (Prior) on Jun 08, 2005 at 02:48 UTC | |
by DouglasDD (Beadle) on Jun 08, 2005 at 14:16 UTC | |
by DouglasDD (Beadle) on Jun 08, 2005 at 14:12 UTC | |
|
Re: top and STDERR hell...
by rdm (Hermit) on Jun 08, 2005 at 03:31 UTC | |
by DouglasDD (Beadle) on Jun 08, 2005 at 14:48 UTC | |
|
Re: top and STDERR hell...
by crusty_collins (Friar) on Jun 07, 2005 at 22:48 UTC | |
|
Re: top and STDERR hell...
by crusty_collins (Friar) on Jun 07, 2005 at 22:23 UTC | |
|
Re: top and STDERR hell...
by zentara (Cardinal) on Jun 08, 2005 at 12:17 UTC | |
by DouglasDD (Beadle) on Jun 08, 2005 at 14:36 UTC | |
by zentara (Cardinal) on Jun 08, 2005 at 19:54 UTC | |
by DouglasDD (Beadle) on Jun 08, 2005 at 22:32 UTC |