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

I'm working on a perl script that plots the output of 'ping'. It's working very nicely, thanks, except that I don't know the terminal width/# of columns, especially if the window gets resized whilst running. I have tried:
my $w = $ENV{COLUMNS};
...which returns an empty string. This kludge-code works (please forgive noisy use of many variables, under development), but not dynamically, and only following
export COLUMNS
before launch:
# get current width from environment chomp (my $w = `echo \$COLUMNS`); if ($w) { $width = $w - 5; }
Can someone point me to a simple, working solution? Thanks!

Replies are listed 'Best First'.
Re: Need nudge: how to (dynamically) discover terminal width?
by Corion (Patriarch) on Nov 24, 2010 at 14:22 UTC

      Note the section on changing window size. WINCH is a signal that you need to trap to be able to do this.

      --MidLifeXis

Re: Need nudge: how to (dynamically) discover terminal width?
by johngg (Canon) on Nov 24, 2010 at 20:16 UTC

    In the past I've used the GetTerminalSize() function from Term::Readkey. I would also set a signal handler for $SIG{WINCH} to call the function again if someone resizes the window.

    I hope this is helpful.

    Cheers,

    JohnGG

Re: Need nudge: how to (dynamically) discover terminal width?
by Khen1950fx (Canon) on Nov 24, 2010 at 18:47 UTC
    If you just want column width, then I'd use Text::CharWidth.
    #!/usr/bin/perl use strict; use warnings; use Text::CharWidth qw(mbswidth); my $string = 'Number of columns?'; print mbswidth($string), "\n";
Re: Need nudge: how to (dynamically) discover terminal width?
by polypagan (Initiate) on Nov 27, 2010 at 17:46 UTC
    Thanks for all the helpful suggestions! I got it working by lifting code from studying okol(http://www.perlmonks.org/?node_id=581144)'s The Last Menu You Need to Write. In my code it looks like
    # Get max display width; either get it via 'resize' for xterms or defa +ult to 180. my ($w) = qx#/usr/bin/resize# =~ /(\d+)/; $w ||= 180;
    Works great ('cause it gets checked every time a histogram needs to be plotted.)
      Okay, I'm back for more. The method I outlined above works fine for Linux, or course. However it isn't transportable (to Mac OS X, in particular), since Mac OS doesn't seem to implement resize at all. I switched to the Term::ReadKey approach (which also works beautifully), which *can* be implemented on Mac by simply installing the module, as in Linux. I am less than satisfied with this, however. What I wrote is a script. Except for certain ping features which require superuser priv, it can be run by any user who can grok "man ping". To make it work with the module, one needs to find, download, make and install Term::ReadKey, which requires superuser access (!) Yes, I know I could just bundle ReadKey.pm and reference it in the current directory... That doesn't seem quite clean either, does it? Anyone have any other ideas? Perhaps I simply need to be satisfied as it is and move on... Again, many thanks for all your help and for this excellent resource! Daniel