Vendredi 23 novembre 2018 (Modifié le Vendredi 23 novembre 2018)

dimension du terminal 2016-12-22T15.18.30

Problème de dimension du terminal lors de connexions à travers un port série

Par Yannick le lundi, 23 février 2015, 19:23 - GNU/Linux - Lien permanent

GNULinux PlanetLibre PlanetRasp RaspberryPi Script 

Amené à travailler avec le terminal, à travers des connexions série, on constate un problème d’ajustement de la taille après l’utilisation de certaines commandes telles que vi etc…

J’utilise généralement la commande suivante pour me connecter sur le port série /dev/ttyUSB0

screen /dev/ttyUSB0 115200

Le problème est que certains logiciels comme l’éditeur vi considèrent que le la fenêtre de terminal n’est que de 24 lignes. Cela reste ainsi ensuite même après être sorti de l’éditeur. Ce qui laisse une bande vide en bas empêchant d’utiliser toute la hauteur du terminal.

serialProblemeLignesVides

serialProblemeLignesVides.png

Le problème, expliqué par Akkana Peck sur son blog est que screen n’a pas de possibilité d’envoyer par le port série, la taille originale de la fenêtre du terminal, (alors que c’est ce qui se passe en SSH par exemple).

Il ne semble pas non plus y avoir une commande qui permet de demander au terminal sa taille.

Cela n’a pas l’air simple à résoudre, heureusement pour nous, Akkana partage un petit script en python qui ruse en allant déplacer le curseur pour trouver la bonne taille etc..

#!/usr/bin/env python

# Get the current size of the terminal window, and set stty size accordingly.
# A replacement for xterm's resize program, with no X dependency.
# Useful when logged in over a serial line.
# Copyright 2013 by Akkana Peck -- share and enjoy under the GPL v2 or later.

import os, sys
import fcntl
import posix
import struct
import time
import re
import termios
import select

tty = open('/dev/tty', 'r+')
tty.write('\033[7\033[r\033[999;999H\033[6n')
tty.flush()

fd = sys.stdin.fileno()

oldterm = termios.tcgetattr(fd)
newattr = oldterm[:]
newattr[3] = newattr[3] & ~termios.ICANON & ~termios.ECHO
termios.tcsetattr(fd, termios.TCSANOW, newattr)

oldflags = fcntl.fcntl(fd, fcntl.F_GETFL)
fcntl.fcntl(fd, fcntl.F_SETFL, oldflags | os.O_NONBLOCK)

try:
    while True:
        r, w, e = select.select([fd], [], [])
        if r:
            output = sys.stdin.read()
            break
finally:
    termios.tcsetattr(fd, termios.TCSAFLUSH, oldterm)
    fcntl.fcntl(fd, fcntl.F_SETFL, oldflags)

rows, cols = map(int, re.findall(r'\d+', output))

fcntl.ioctl(fd, termios.TIOCSWINSZ,
            struct.pack("HHHH", rows, cols, 0, 0))

print "\nReset the terminal to", rows, "rows", cols, "cols"

et permet de résoudre le problème.

TerminalSerialResolution

TerminalSerialResolution.png

On peut également le mettre par exemple dans le fichier .bash_profile pour qu’il se lance à l’ouverture de la session.