ventana de consola serie redimensionable?


25

Cuando uso la consola serie de mi sistema siempre termino con $COLUMNS=80y $LINES=24.

Si bien puedo cambiar estas variables manualmente, es algo molesto hacerlo en cualquier momento cuando la ventana del terminal del lado del cliente ha cambiado de tamaño.

Por lo general, me estoy conectando a la consola usando screen /dev/mytty baudrate.

Cambiar la $TERMvariable de entorno a "pantalla" o "xterm" no ayuda.

¿Tendré que llamar gettycon algunos de ellos en lugar de vt100?

No hace falta decir que todo esto funciona bien cuando me conecto a la misma máquina usando ssh.

Respuestas:


26

Al igual que los comentaristas antes mencionados, no hay alternativa a llamar resizedespués de cada comando, si no tiene este comando y no desea instalar un paquete donde está ( xterm), aquí hay dos secuencias de comandos de shell POSIX que hacen lo mismo utilizando códigos de escape de 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"
}

Por cierto, en mi .profilearchivo encontrará lo siguiente: [ $(tty) = /dev/ttyS0 ] && res para que el tamaño del terminal se determine en cada inicio de sesión a través de la línea serie (la que uso para la administración), por ejemplo, después de reiniciar el dispositivo.
Vea también la idea de rsaw en los comentarios para tener la línea [ $(tty) = /dev/ttyS0 ] && trap res2 DEBUGallí en su lugar para que el cambio de tamaño se ejecute después de cada comando (tenga en cuenta que AFAIK no siempre es posible o no busybox).


3
PD: Para hacer más permanente, agregue [[ $(tty) == /dev/ttyS0 ]] && trap res2 DEBUGa una de las configuraciones de perfil de shell (por ejemplo /etc/profile, ~/.bash_profile). Esto hará que se ejecute después de cada comando (lo que sería bueno si cambia el tamaño de ventanas / paneles con screen / tmux / terminal-emulator).
rsaw

2
Después de usarlo durante unos pocos minutos me di cuenta rápidamente de que tanto resy res2son demasiado lentos para nada más que su uso en el primer inicio de sesión. En mis máquinas, ambos tardan 0.5 segundos en terminar ... haciendo que todos mis comandos parezcan lentos (cuando se usan con DEBUG trap). Whoops! No puedo tener eso. Supongo que voy a instalar xterm.
rsaw

3
@phk xterm's resizees muchísimo más rápido, generalmente 0.002seg.
rsaw

1
@rsaw Oh OK, es bueno saberlo, pensé que se comportaría de manera similar y, por lo tanto, sería similarmente lento Recuerdo que el que en algunos busyboxcasos parecía ser tan lento para mí.
phk

1
Gracias por esta solución independiente. Estoy usando una distribución solo para consola que no tiene x11 o xterm instalado, por resizelo que no es una opción.
thom_nic

16

Solo para que conste, aquí está la respuesta a este problema (Usenet ganó):

Las aplicaciones de consola que se ejecutan dentro de las aplicaciones de terminal virtual ( xterm, rxvty amigos) recibiránSIGWINCH después de una operación de cambio de tamaño ha tenido lugar. Por lo tanto, la aplicación podrá volver a dibujar la ventana, etc. en el controlador de señal correspondiente.

Desafortunadamente cuando se usa una consola en serie, no existe tal mecanismo.

Sin embargo, es posible que la aplicación solicite activamente la información actual. tamaño ventana de la consola. Entonces, la segunda mejor opción es hacer esto cada vez que el shell imprime un símbolo del sistema.

Esto se puede lograr compilando primero un ejecutable de cambio de tamaño especial y luego usando lo siguiente en bashrc:

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

Por supuesto, esto no cambiará la configuración del tamaño de la consola en una aplicación de consola durante el tiempo de ejecución.


1
¿No debería ser posible ejecutar un protocolo a través de la línea serie, que no ofrecen todas las características? Quiero decir que tenemos un cliente y un servidor. ¡Podrían usar secuencias de escape en banda para hacer casi todo, y aún así trabajar con una consola en serie de texto plano!
Evi1M4chine

1
En realidad, el comentario en el código deja en claro que no es la versión de la resizecual está instalada en su sistema.
Thomas Dickey

9

Los terminales "redimensionables" como tales son el resultado de NAWS ( Negotiate About Window Sizede la opción de tamaño de ventana Telnet RFC 1073 ).

Si está conectado directamente a la computadora mediante un puerto serie, no hay negociación involucrada y la computadora no tiene conocimiento directo del tamaño de pantalla de su terminal.

Si una terminal puede negociar el tamaño, la computadora enviará SIGWINCH a las aplicaciones que se ejecutan en el terminal, diciéndoles que actualicen su noción del de la pantalla.

Cuando la computadora no conoce el tamaño de la pantalla, generalmente establece el tamaño mostrado por stty -a(filas y columnas) en cero. Para uso interactivo, esto es un poco hostil, y algunos sistemas usan variables de entorno LINESy COLUMNSpara ayudar. Los valores asignados pueden derivarse de la descripción del terminal; más a menudo son simplemente codificados. La convención para estas variables requiere que surtan efecto a menos que se supriman explícitamente, por ejemplo, en la use_envfunción de aplicaciones de maldiciones . En el lado positivo, esas variables pueden ser útiles cuando no hay información confiable disponible. En el lado negativo, no existe un método conveniente para alterar esas variables.

El resizeprograma (una utilidad provista con xterm) puede usar la secuencia de escape del informe de posición del cursor estilo VT100 para determinar el tamaño de la pantalla. Esto se puede ejecutar desde la línea de comandos; (de nuevo) no hay una forma conveniente de hacerlo automáticamente. Como efecto secundario, resizeactualiza la información sobre las filas / columnas vistas por stty. Su uso para proporcionar variables de entorno actualizadas es principalmente útil para casos como este, dónde LINESy COLUMNS se establecen, y debe actualizarse.


3

Aquí hay otra solución que funcionó muy bien para mí en mi sistema Linux incorporado (Overo ejecutando Angstrom). Acabo de ejecutarlo desde mi archivo .bashrc. No quería usar redimensionar porque eso requiere instalar algunos paquetes X, y no quería eso.

Decirle a su Raspberry Pi que su terminal tiene más de 24 líneas | Blog de pensamientos superficiales


3
Por favor, no acaba de publicar un enlace: incluir los detalles pertinentes para que la información está disponible aquí, así ...
jasonwryan

1
Lástima que necesita Python.
Craig McQueen el


1

Al ejecutar una sesión de shell en una línea en serie, es suficiente llamar al resizecomando dentro de esa sesión, después de establecer la conexión y después de cada cambio de geometría de terminal.

El resizecomando es parte de xterm pero no depende de X11. Por ejemplo, en Fedora se empaqueta por separado como xterm-resize.

Cómo funciona: el comando de cambio de tamaño mide la altura / anchura a través de algunos movimientos del cursor y luego envía esos valores al terminal a través de secuencias de escape.

Con un shell como zsh, esto también actualiza automáticamente las variables LINESy COLUMNS(alternativamente, uno puede evaluar las declaraciones de exportación que los comandos imprimen en stdout).

Por qué esto es necesario: con una sesión local o ssh, el terminal puede señalar a la sesión los cambios de geometría (cf. SIGWINCH). Este mecanismo no funciona a través de una conexión en serie.


0

Aquí hay una función de cambio de tamaño simple y rápida que funciona solo para bash. Se modifica a partir de resk de phk, haciendo uso de bash read -d delimpara evitar dejar que el tiempo de espera termine de leer.

resize() {
  old=$(stty -g)
  stty -echo
  printf '\033[18t'
  IFS=';' read -d t _ rows cols _
  stty "$old"
  stty cols "$cols" rows "$rows"
}
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.