web-dev-qa-db-fra.com

Comment trouver la largeur et la hauteur d'une fenêtre de terminal?

À titre d’exemple simple, je souhaite écrire un script CLI pouvant imprimer un "=" sur toute la largeur de la fenêtre du terminal.

#!/usr/bin/env php
<?php
echo str_repeat('=', ???);

ou

#!/usr/bin/env python
print '=' * ???

ou

#!/usr/bin/env bash
x=0
while [ $x -lt ??? ]; do echo -n '='; let x=$x+1 done; echo
238
too much php
  • tput cols vous indique le nombre de colonnes.
  • tput lines vous indique le nombre de lignes.
451
TonyUser

Dans bash, les variables d'environnement $LINES et $COLUMNS devraient pouvoir faire l'affaire. Le sera automatiquement défini lors de tout changement de la taille du terminal. (c'est-à-dire le SIGWINCH signal)

82
David Dean

Et il y a stty , from coreutils

$ stty size
60 120 # <= sample output

Il imprimera le nombre de lignes et de colonnes, ou la hauteur et la largeur, respectivement.

Ensuite, vous pouvez utiliser cut ou awk pour extraire la partie souhaitée.

C'est stty size | cut -d" " -f1 pour la hauteur/lignes et stty size | cut -d" " -f2 pour la largeur/colonnes

52
ryenus
yes = | head -n$(($(tput lines) * $COLUMNS)) | tr -d '\n'
15
pixelbeat

Pour ce faire dans un environnement CLI Windows, le meilleur moyen que je puisse trouver consiste à utiliser la commande mode et à analyser le résultat.

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;
}

J'espère que c'est utile!

NOTE: La hauteur renvoyée est le nombre de lignes dans la mémoire tampon, ce n'est pas le nombre de lignes visibles dans la fenêtre. De meilleures options sur le marché?

12
lyceus

Sous POSIX, vous souhaitez invoquer l'appel TIOCGWINSZ (Get WINdow SiZe) ioctl(). La plupart des langues devraient avoir une sorte de wrapper pour cela. Dans Perl, vous pouvez utiliser Terme :: Taille :

use Term::Size qw( chars );

my ( $columns, $rows ) = chars \*STDOUT;
9
LeoNerd

Comme je l'ai mentionné dans la réponse lyceus, son code échouera sur les paramètres régionaux non anglais de Windows, car la sortie de mode ne peut pas contenir les sous-chaînes "colonnes" ou "lignes":

mode command output

Vous pouvez trouver la sous-chaîne correcte sans chercher de texte:

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

Notez que je ne me préoccupe même pas des lignes parce que ce n'est pas fiable (et que je m'en fiche en fait).

Edit: Selon les commentaires sur Windows 8 (oh you ...), je pense que cela pourrait être plus fiable:

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

Faites le test cependant, parce que je ne l'ai pas testé.

4
Camilo Martin

Inspiré par la réponse de @ pixelbeat, voici une barre horizontale créée par tput, légère utilisation abusive de printf padding/filling et tr 

printf "%0$(tput cols)d" 0|tr '0' '='
1
huoneusto

Dans certains cas, vos lignes/lignes et vos colonnes ne correspondent pas à la taille réelle du "terminal" utilisé. Peut-être que vous n'avez peut-être pas de "tput" ou de "stty" disponible.

Voici une fonction bash que vous pouvez utiliser pour vérifier visuellement la taille. Cela fonctionnera jusqu'à 140 colonnes x 80 lignes. Vous pouvez ajuster les maximums au besoin.

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
pourhaus