À 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
tput cols
vous indique le nombre de colonnes.tput lines
vous indique le nombre de lignes.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)
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
yes = | head -n$(($(tput lines) * $COLUMNS)) | tr -d '\n'
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é?
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;
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":
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é.
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' '='
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"
}