jason0 has asked for the wisdom of the Perl Monks concerning the following question:

My perl program is continuously running like vmstat or iostat. I would like it to mimic how vmstat/iostat rewrites the column headers as the number of rows gets near the lines per screen (or some such).

I could read things like the $= variable ($FORMAT_LINES_PER_PAGE) or some such. But how do I have my program resize based on a window resize?

thus:

When I change the size of my terminal window (xterm, maybe ssh via xterm to another system)

  1. how can window resizing information be passed on to the running perl process (such as sigwinch) then
  2. how do I resize my output parameters to match.

Replies are listed 'Best First'.
Re: handling terminal window resizing
by LanX (Saint) on Dec 30, 2016 at 00:21 UTC
    I googled for you

    > 1. how can window resizing information be passed on to the running perl process (such as sigwinch) then

    assign a coderef to $SIG{WINCH}

    > 2. how do I resize my output parameters to match.

    Without knowing your code, I'd say try to access the settings in the callback

    see also To find out console line size in char.s .

    you may also want to give Curses a try.

    Cheers Rolf
    (addicted to the Perl Programming Language and ☆☆☆☆ :)
    Je suis Charlie!

Re: handling terminal window resizing
by kcott (Archbishop) on Dec 30, 2016 at 06:14 UTC

    G'day jason0,

    You provide very little in the way of details, which means that only a very generalised solution can be provided.

    Here's some suggestions based on the assumption that you have code something like:

    open my $cmd_pipe, '-|', 'iostat -w1';

    And that you're reading from $cmd_pipe line-by-line which, in turn, forms the basis for what you output to the screen (and without any knowledge of what the header line(s) look like).

    • You could use Term::Size::Any (or similar) to get the current terminal size. Then, based on a count of the lines already output and the number of lines needed for the header, conditionally output a new header.
    • Take a look at "perlipc: Signals" for information on signal handling.
    • Some sort of GUI front-end (e.g. Tk) might be an alternative to consider.

    — Ken

Re: handling terminal window resizing
by johngg (Canon) on Dec 30, 2016 at 12:00 UTC

    Here's a little test program I built a while back to try this out. Run it in a terminal window such xterm and it will report the terminal size as you change it.

    use strict; use warnings; use feature qw{ say }; $SIG{ WINCH } = \ &winch; winch(); while ( 1 ) { sleep 200; } sub winch { my( $rows, $cols ) = getRowsCols(); say qq{Rows = $rows - Columns = $cols}; } sub getRowsCols { my $sttyOut = do { open my $sttyFH, q{-|}, qw{ /bin/stty size } or die qq{fork: /bin/stty size: $!\n}; local $/; <$sttyFH>; }; die qq{/bin/stty size: Unexpected output: $sttyOut} unless $sttyOut =~ m{^(\d+)\s+(\d+)$}; return $1, $2; }

    I hope this is helpful.

    Cheers,

    JohnGG

      I would write your getRowsCols-sub like this:
      sub getRowsCols { qx|/bin/stty size| =~ /(\d+)\s+(\d+)/; }
      Is there anything gained in your (more complicated imho) way?
        > Is there anything gained in your (more complicated imho) way?

        Well he has 2 points of error handling.

        Cheers Rolf
        (addicted to the Perl Programming Language and ☆☆☆☆ :)
        Je suis Charlie!