in reply to unexplained output from top in batch mode

UPDATE: Would you mind restating, "'home/zentara/bin/claws' shows up as a name 3 in the output.?" I may not have answered anything relevent in the rest of this post.

I don't think split /s\+/ is going to be very robust here. The columns have a certain width and the fields may have spaces in them... A ways back I had written a funny little toy that I seem to use over and over. Perhaps I should make it into a proper module.

package magic_columator; use strict; use Carp; our $TABS_MODE = undef; 1; sub test_fetchrow { my $this = shift; my @row = $this->fetchrow; print Dumper([$this->{format}, @row]), "\n"; } sub fetchrow { my $this = shift; my $fh = $this->{IN}; if( my $line = <$fh> ) { my @a = (); if( $TABS_MODE ) { @a = split(/$TABS_MODE/, $line); } else { @a = unpack($this->{format}, $line); } s/^\s+// for @a; s/\s+$// for @a; return @a; } return (); } sub new { my $class = shift; my $this = bless {}, $class; my $file = shift; croak "couldn't find file \"$file\"" unless -f $file; $this->{file} = $file; $this->find_seps; open $this->{IN}, $this->{file}; return $this; } sub find_seps { my $this = shift; open IN, $this->{file} or die "couldn't open $this->{file} for rea +d: $!"; my @spaces = (); while(<IN>) { my $x = 0; while( m/(.)/g ) { my $c = $1; $x ++; push @spaces, 1 while @spaces < $x; $spaces[$x-1] = 0 unless $c eq ' '; } } close IN; $this->{format} = ""; my $x = 0; for my $c (@spaces) { $x ++; if( $c ) { if( $x>1 ) { $this->{format} .= "A$x"; $x = 0; } $this->{format} .= " "; } } if( $x ) { $this->{format} .= "A$x"; } }

It'd work like so:

use magic_columator; while(my @row = $col->fetchrow) { # do stuff }

This would be a great place to use iterators I think. There are also probably already modules that do this more cleanly. If you were to use it, or something like it, it'd need some major updates and fixes I suspect.

-Paul

Replies are listed 'Best First'.
Re^2: unexplained output from top in batch mode
by zentara (Cardinal) on Jan 13, 2007 at 13:07 UTC
    Well, if you use the script in ztk-visual-top-w-kill, and go into the thread where I sysread top's output. and print the $buf,
    sysread(READ,$buf,8192); print "$buf\n\n";
    you will see that top's batch output is setting the name to 3 (at least on my machine for /home/zentara/bin/claws), when it's still a string, before any split occurs.

    So the question is whether it is top's -b option that does this, or does the IPC::Open3 pipe somehow change it?

    When top is run in normal mode(like in an xterm), the name is shown correctly.

    Also if I do "top -b >>top.output", the name is shown correctly as "claws". So somehow, coming thru the IPC::OPen3 pipe is causing it to change. Is it possible that a pipe is interpreted to be a weird terminal type (not vt100)?


    I'm not really a human, but I play one on earth. Cogito ergo sum a bum

      K, then I stand by my previous guess. Sometimes columns can have embedded spaces (like the leading spaces on RES and SHR, etc), and I think that might be messing up your column numbers. If it's just the one process getting renamed, I'd look for something stranger going on, but somehow I think it's going to relate to split /\s+/

      -Paul

        Thanks for looking at it, but now I think it is something weird with Claws output. When I look at the entry for the pid in /proc, the name is different in different places. In /proc/$pid/cmdline, it is correctly shown as 'claws'. But in /proc/$pid/status, it shows it's Name as 3. So I think it is a problem with Sylpheed-Claw's way of reporting iteslf? Every other process seems to have Name and cmdline as the same (or similar).

        I'm not really a human, but I play one on earth. Cogito ergo sum a bum