How do I find the width & height of a terminal window?

前端 未结 9 1031
滥情空心
滥情空心 2020-12-04 04:33

As a simple example, I want to write a CLI script which can print = across the entire width of the terminal window.

#!/usr/bin/env php


        
相关标签:
9条回答
  • 2020-12-04 05:15

    As I mentioned in lyceus answer, his code will fail on non-English locale Windows because then the output of mode may not contain the substrings "columns" or "lines":

                                             mode command output

    You can find the correct substring without looking for text:

     preg_match('/---+(\n[^|]+?){2}(?<cols>\d+)/', `mode`, $matches);
     $cols = $matches['cols'];
    

    Note that I'm not even bothering with lines because it's unreliable (and I actually don't care about them).

    Edit: According to comments about Windows 8 (oh you...), I think this may be more reliable:

     preg_match('/CON.*:(\n[^|]+?){3}(?<cols>\d+)/', `mode`, $matches);
     $cols = $matches['cols'];
    

    Do test it out though, because I didn't test it.

    0 讨论(0)
  • 2020-12-04 05:17

    There are some cases where your rows/LINES and columns do not match the actual size of the "terminal" being used. Perhaps you may not have a "tput" or "stty" available.

    Here is a bash function you can use to visually check the size. This will work up to 140 columns x 80 rows. You can adjust the maximums as needed.

    function term_size
    {
        local i=0 digits='' tens_fmt='' tens_args=()
        for i in {80..8}
        do
            echo $i $(( i - 2 ))
        done
        echo "If columns below wrap, LINES is first number in highest line above,"
        echo "If truncated, LINES is second number."
        for i in {1..14}
        do
            digits="${digits}1234567890"
            tens_fmt="${tens_fmt}%10d"
            tens_args=("${tens_args[@]}" $i)
        done
        printf "$tens_fmt\n" "${tens_args[@]}"
        echo "$digits"
    }
    
    0 讨论(0)
  • 2020-12-04 05:20

    In bash, the $LINES and $COLUMNS environmental variables should be able to do the trick. The will be set automatically upon any change in the terminal size. (i.e. the SIGWINCH signal)

    0 讨论(0)
  • 2020-12-04 05:21

    To do this in Windows CLI environment, the best way I can find is to use the mode command and parse the output.

    function getTerminalSizeOnWindows() {
      $output = array();
      $size = array('width'=>0,'height'=>0);
      exec('mode',$output);
      foreach($output as $line) {
        $matches = array();
        $w = preg_match('/^\s*columns\:?\s*(\d+)\s*$/i',$line,$matches);
        if($w) {
          $size['width'] = intval($matches[1]);
        } else {
          $h = preg_match('/^\s*lines\:?\s*(\d+)\s*$/i',$line,$matches);
          if($h) {
            $size['height'] = intval($matches[1]);
          }
        }
        if($size['width'] AND $size['height']) {
          break;
        }
      }
      return $size;
    }
    

    I hope it's useful!

    NOTE: The height returned is the number of lines in the buffer, it is not the number of lines that are visible within the window. Any better options out there?

    0 讨论(0)
  • 2020-12-04 05:24
    yes = | head -n$(($(tput lines) * $COLUMNS)) | tr -d '\n'
    
    0 讨论(0)
  • 2020-12-04 05:25

    On POSIX, ultimately you want to be invoking the TIOCGWINSZ (Get WINdow SiZe) ioctl() call. Most languages ought to have some sort of wrapper for that. E.g in Perl you can use Term::Size:

    use Term::Size qw( chars );
    
    my ( $columns, $rows ) = chars \*STDOUT;
    
    0 讨论(0)
提交回复
热议问题