fenêtre de console série redimensionnable?

25

Lorsque j'utilise la console série de mon système, je me retrouve toujours avec $COLUMNS=80et $LINES=24.

Bien que je puisse modifier ces variables manuellement, il est quelque peu ennuyeux de le faire à tout moment lorsque la fenêtre du terminal côté client a été redimensionnée.

Habituellement, je me connecte à la console à l'aide de screen /dev/mytty baudrate.

Changer la $TERMvariable d'environnement en "screen" ou "xterm" n'aide pas.

Aurai-je besoin d'appeler gettyavec certains d'entre eux au lieu de vt100?

Inutile de dire que tout cela fonctionne bien, lorsque je me connecte à la même machine en utilisant ssh.

Sven Geggus
la source

Réponses:

26

Comme les commentateurs avant moi, il n'y a pas d'alternative à appeler resizeaprès chaque commande, si vous n'avez pas cette commande et que vous ne voulez pas installer un paquet là où il est ( xterm), voici deux scripts shell POSIX qui font la même chose en utilisant les codes d'échappement du terminal ANSI:

res() {

  old=$(stty -g)
  stty raw -echo min 0 time 5

  printf '\0337\033[r\033[999;999H\033[6n\0338' > /dev/tty
  IFS='[;R' read -r _ rows cols _ < /dev/tty

  stty "$old"

  # echo "cols:$cols"
  # echo "rows:$rows"
  stty cols "$cols" rows "$rows"
}

res2() {

  old=$(stty -g)
  stty raw -echo min 0 time 5

  printf '\033[18t' > /dev/tty
  IFS=';t' read -r _ rows cols _ < /dev/tty

  stty "$old"

  # echo "cols:$cols"
  # echo "rows:$rows"
  stty cols "$cols" rows "$rows"
}

BTW, dans mon .profilefichier, vous trouverez les éléments suivants: [ $(tty) = /dev/ttyS0 ] && res afin que la taille du terminal soit déterminée à chaque connexion sur la ligne série (celle que j'utilise pour la gestion), par exemple après le redémarrage de l'appareil.
Voir aussi l'idée de rsaw dans les commentaires d'avoir la ligne à la [ $(tty) = /dev/ttyS0 ] && trap res2 DEBUGplace donc le redimensionnement s'exécute après chaque commande (notez que AFAIK n'est pas ou pas toujours possible busyboxcependant).

phk
la source
3
PS: Pour rendre plus permanent, ajoutez [[ $(tty) == /dev/ttyS0 ]] && trap res2 DEBUGà l'une des configurations de profil de shell (par exemple /etc/profile, ~/.bash_profile). Cela le fera s'exécuter après chaque commande (ce qui ne serait une bonne chose que si vous redimensionnez les fenêtres / volets avec screen / tmux / terminal-emulator).
vu
2
Après avoir utilisé pendant quelques minutes , je suis vite rendu compte que les deux reset res2sont trop lents pour quoi que ce soit , mais une utilisation sur la première connexion. Sur mes machines, elles prennent toutes les deux 0,5 secondes pour terminer ... ce qui rend toutes mes commandes lentes (lorsqu'elles sont utilisées avec le piège DEBUG). Oups! Je ne peux pas avoir ça. Je suppose que je vais installer xterm.
vu
3
@phk xterm resizeest waaaay plus rapide - généralement 0,002 s.
vu
1
@rsaw Oh OK, bon à savoir, je pensais que cela se comporterait de la même manière et serait donc tout aussi lent. Je me souviens que celle de certains busyboxsemblait être tout aussi lente pour moi.
phk
1
Merci pour cette solution autonome. J'utilise une distribution console uniquement qui n'a pas installé x11 ou xterm, ce resizen'est donc pas une option.
thom_nic du
16

Juste pour mémoire, voici la réponse à ce problème (Usenet a gagné):

Applications console en cours d' exécution dans les applications de terminal virtuel ( xterm, rxvtet amis) recevront SIGWINCHaprès une opération de modification de taille a eu lieu. Ainsi, l'application pourra redessiner la fenêtre, etc. dans le gestionnaire de signaux correspondant.

Malheureusement, lors de l'utilisation d'une console série, il n'existe aucun mécanisme de ce type.

Il est cependant possible pour l'application de demander activement la taille actuelle de la fenêtre de la console. Donc, la deuxième meilleure chose à faire est de le faire chaque fois qu'une invite de commande est imprimée par le shell.

Ceci peut être réalisé en compilant d' abord un exécutable de redimensionnement spécial , puis en utilisant ce qui suit dans bashrc:

if [ $(tty) == '/dev/ttyS0' ]; then
  trap resize DEBUG
fi

Bien sûr, cela ne changera pas les paramètres de taille de la console dans une application console pendant l'exécution.

Sven Geggus
la source
1
Il ne devrait pas être possible d'exécuter un protocole sur la ligne série, qui n'offre toutes les fonctionnalités? Je veux dire que nous avons un client et un serveur. Ils pourraient utiliser des séquences d'échappement intrabande pour faire à peu près tout, tout en travaillant avec une console série en texte brut!
Evi1M4chine
1
En fait, le commentaire dans le code montre clairement que ce n'est pas la version resizequi est installée sur votre système.
Thomas Dickey
9

Les terminaux "redimensionnables" en tant que tels sont le résultat de NAWS ( Negotiate About Window Sizede RFC 1073 Telnet Window Size Option ).

Si vous êtes connecté directement à l'ordinateur via un port série, aucune négociation n'est impliquée et l'ordinateur n'a aucune connaissance directe de la taille d'écran de votre terminal.

Si un terminal peut négocier la taille, l'ordinateur enverra SIGWINCHaux applications s'exécutant dans le terminal, leur disant de mettre à jour leur notion de taille d'écran.

Lorsque l'ordinateur ne connaît pas la taille de l'écran, il définit généralement la taille indiquée par stty -a(lignes et colonnes) sur zéro. Pour une utilisation interactive, c'est un peu hostile, et certains systèmes utilisent des variables d'environnement LINESet COLUMNSpour aider. Les valeurs attribuées peuvent être dérivées de la description du terminal; le plus souvent, ils sont simplement codés en dur. La convention pour ces variables exige qu'elles prennent effet à moins qu'elles ne soient explicitement supprimées, par exemple dans la use_envfonction des applications curses . Du côté positif, ces variables peuvent être utiles lorsqu'aucune information fiable n'est disponible. Du côté négatif, il n'y a pas de méthode pratique pour modifier ces variables.

Le resizeprogramme (un utilitaire fourni avec xterm) peut utiliser la séquence d'échappement du rapport de position du curseur de style VT100 pour déterminer la taille de l'écran. Cela peut être exécuté à partir de la ligne de commande; il n'y a (encore) aucun moyen pratique de le faire automatiquement. En tant qu'effet secondaire, resizemet à jour les informations sur les lignes / colonnes vues par stty. Son utilisation pour fournir des variables d'environnement mises à jour est principalement utile dans des cas comme celui-ci, où LINESet COLUMNS sont définis, et doit être mis à jour.

Thomas Dickey
la source
3

Voici une autre solution qui a très bien fonctionné pour moi sur mon système Linux embarqué (Overo exécutant Angstrom). Je viens de l'exécuter à partir de mon fichier .bashrc. Je ne voulais pas utiliser le redimensionnement car cela nécessite l'installation de certains packages X, et je ne le voulais pas.

Dire à votre Raspberry Pi que votre terminal est plus grand que 24 lignes | Blog sur les pensées superficielles

Bière Austin
la source
3
Veuillez ne pas poster un lien: incluez les détails pertinents pour que les informations soient également disponibles ici ...
jasonwryan
1
Dommage qu'il ait besoin de Python.
Craig McQueen
1

Dans le cas où vous pourriez utiliser FreeBSD à la place, il y a la commande resizewin (1) , qui fait exactement ce que vous voulez.

Edward Tomasz Napierala
la source
1

Lors de l'exécution d'une session shell sur une ligne série, il suffit d'appeler la resizecommande à l'intérieur de cette session - après avoir établi la connexion et après chaque changement de géométrie du terminal.

La resizecommande fait partie de xterm mais ne dépend pas de X11. Par exemple, sur Fedora, il est emballé séparément en tant que xterm-resize.

Comment ça marche: la commande resize mesure la hauteur / largeur via quelques mouvements de curseur puis envoie ces valeurs au terminal via des séquences d'échappement.

Avec un shell comme zsh, cela met également automatiquement à jour les variables LINESet COLUMNS(en variante, on peut évaluer les instructions d'exportation que les commandes impriment sur stdout).

Pourquoi cela est nécessaire: avec une session locale ou ssh, le terminal est en mesure de signaler la session sur les changements de géométrie (cf. SIGWINCH). Ce mécanisme ne fonctionne pas sur une connexion série.

maxschlepzig
la source
0

Voici une fonction de redimensionnement simple et rapide qui ne fonctionne que pour bash. Il est modifié à partir de resk de phk, en utilisant bash read -d delimpour éviter de laisser le délai d'attente pour terminer la lecture.

resize() {
  old=$(stty -g)
  stty -echo
  printf '\033[18t'
  IFS=';' read -d t _ rows cols _
  stty "$old"
  stty cols "$cols" rows "$rows"
}
Gary Guo
la source