Lo hice y lo entendí

El blog de Vicente Navarro
28 jul

Terminales para Cygwin. Notas sobre Terminfo y Termcap.

Llevamos varias entradas ya hablando del Cywin. En la de Instalar un Cygwin portable en una memoria USB comentaba que el Cygwin se usa normalment en una ventana de CMD de Windows. El tipo de terminal que usa Cygwin cuando funciona dentro de un CMD es cygwin:

vnavarro@DARKSTAR ~
$echo $TERM
cygwin

Cada tipo de terminal supone una forma diferente de hacer scrolling, de mover las líneas por la pantalla, los retornos de carro y de línea, de borrar el carácter anterior, de limpiar la pantalla, de conocer el número de líneas y columnas, de cómo usar colores y si se pueden usar, etc. Para la mayoría de aplicaciones de línea de comandos típicas de UNIX (por ejemplo, ls, awk, sed, grep, cat, mv, cp), todas estas especificaciones son indiferentes: Ellas toman la información que necesitan de sus argumentos de la línea de comandos o de la entrada estándar y sacan los resultados a través de la salida estándar y del código de error. Pueden incluso funcionar sin un terminal. Sin embargo, hay muchas otras aplicaciones que tienen que conocer muy bien cómo mover y posicionar texto por el terminal, como por ejemplo el vim, el mc, o el top.

Para que las aplicaciones que lo necesiten puedan interactuar con los múltiples tipos diferentes de terminales, las aplicaciones pueden usar, bien la librería Termcap, bien la librería ncurses junto con la base de datos de terminales Terminfo.

El Terminfo almacena la información de todos los tipos de terminal en /usr/share/terminfo. Dentro de ese directorio, por ejemplo el fichero c/cygwin almacena la información sobre el tipo de terminal que por defecto usa el Cygwin en el CMD de Windows, y el fichero v/vt100 almacena el tipo de terminal más común y más emulado.

El Termcap también tiene su (mucho más pequeña) base de datos de terminales centralizada en un fichero único, el /etc/termcap. Podemos usar herramientas como el infocmp -C o el captoinfo (herramientas incluidas en el ncurses) para pasar la configuración para un tipo de terminal de un formato al otro.

Hoy en día se usa muchísimo más el ncurses+Terminfo, pero estoy haciendo énfasis en el Termcap porque resulta que el Cygwin, aunque actualmente también incluye el Terminfo, históricamente ha usado el Termcap por ser mucho menos pesada para distribuir, como podemos leer en la lista de distribución de Cygwin: Re: less problem:

On Sat, May 27, 2000 at 12:03:10PM -0400, Jason Tishler wrote:
>
>I really wished that Cygwin already included terminfo versions of less,
>texinfo, etc., and ncurses (ie, terminfo) too.
>

Can I ask why?  I don't see much sense in downloading megabytes of information
and installing it on your system so that you get the same functionality as
comes from a 9745 byte termcap file.

Cygwin en CMD: $TERM

mc en cygwin

El problema del Cygwin ejecutado dentro de un CMD de Windows es que al conectarnos a otros sistemas UNIX (por ejemplo al conectarnos a HP-UX o Solaris con el cliente de SSH o de telnet del Cygwin) podemos encontrarnos con que el terminal no es reconocido:

Type cygwin unknown

Value of TERM has been set to "unknown".

# top
Sorry, I need to know a more specific terminal type than 'unknown'.

Esto no pasa con Linux, porque Linux sí que usa el Terminfo estándar que incluye información para el $TERM cygwin.

Para evitar este problema con el terminal cygwin, una solución muy versátil es habilitar el servidor de SSH, Telnet o rlogin y acceder con cualquier cliente de estos protocolos que emule el tipo de terminal que nos interese. El cliente free más popular con diferencia es el PuTTY: Es cliente de los tres protocolos que mencionaba anteriormente y además es un terminal de tipo xterm.

putty conectando a Cygwin

Otra excelente solución muy usada es instalar el servidor X.org de Cygwin y abrir una ventana xterm o rxvt. Las siguientes capturas muestran una ventana de xterm y otra de rxvt:

xterm Cygwin

rxvt X11 Cygwin

Pero respecto al rxvt del Cygwin, hay algo importantísimo: ¡Es capaz de funcionar sin servidor de X! Para ello, podemos ver que el paquete lleva una librería libW11.dll que es la que permite este comportamiento:

vnavarro@DARKSTAR ~
$ cygcheck -l rxvt
/usr/bin/libW11.dll
/usr/bin/rxvt.exe

El documento /usr/share/doc/Cygwin/rxvt-version.README nos cuenta qué tiene que ocurrir para que cargue la versión X11 o la W11:

Win32 enabled rxvt README

rxvt is a color vt102 terminal emulator intended as a replacement
for xterm(1) and cmd.com.

[...]

================
Display, or "how can I get rxvt to connect to my X-server at :0"

Here's some options:
1) run your X-server as :1 (it is, after all, the second display)
2) set DISPLAY to localhost:0
3) set W11_LIBRARY to libX11

================
Does X need to be installed?

No, unless you want to have rxvt display on an X-display.  The executable
will dynamically load the appropriate library.  The order it searches is:
1. $W11_LIBRARY if set
2. cygX11-9, cygX11-8, cygX11-7, cygX11-6, libX11, if $DISPLAY is set
3. libW11

En la captura que aparece a continuación, podemos ver que el rxvt mostrado en ella funciona sin servidor de X por el icono de arriba a la izquierda: Es diferente del icono estándar representando una X que aparece en la captura anterior.

rxvt W11 Cygwin

La opción que a mí más me gusta es el PuTTYcyg, una modificación del Putty que permite usar esta aplicación como terminal de Cygwin sin más complicaciones. La única pequeña pega que tiene es que mientras que a mí me gusta usar la versión portable de PuTTY: portaPuTTY, no hay versión portable del PuTTYcyg.

Para usarlo, simplemente lo ejecutamos, seleccionamos conexión Cygterm y ponemos un guión en el recuadro de command:

PuTTYcyg

Cygwin en el PuTTYcyg

Para finalizar, vamos a comentar el Terminator, cliente que he conocido gracias a un comentario de Barrapunto. Según el autor, el Terminator es…

Terminator is a cross-platform GPL terminal emulator with advanced features not yet found elsewhere.

Terminator will run on any modern OS with Java 5 or later. It replaces xterm, rxvt, xwsh and friends on X11 systems, GNOME Terminal, KDE’s Konsole, Apple’s Terminal.app, and PuTTY on MS Windows.

Usar Terminator para el Cygwin está bien, sobre todo porque permite tener varios terminales en distintos tabs.

El único requisito específico para instalar el Terminator en Windows con Cygwin, es tener instalado el paquete del Ruby.

Sin embargo, el Terminator tiene un problema importante: Sólo puede usar el tipo de terminal terminator, que no es estándar y no está incluido en las distribuciones de Linux ni en Cygwin. Al instalarlo, él añade información específica de su tipo de terminal en el directorio del usuario ~/.terminfo/t/terminator y en el directorio global /usr/share/terminfo/t/terminator (si los permisos del usuario que hace la instalación lo permiten).

Cygwin en el Terminator

Aunque el tipo de terminal del Terminator quede bien configurado en el sistema local, si desde éste nos conectamos a otro, lo más seguro es que el tipo de terminal no sea reconocido, lo cual limita mucho su utilidad.

Incluso aunque en el propio sistema el Terminfo quede bien configurado, como ya comentábamos antes, muchas partes de Cygwin siguen usando el Termcap (p.e. el less). Para que estos programas funcionen bien con Terminator, tenemos que crear una entrada de Termcap para este tipo de terminal con el comando:

infocmp -C >> ~/.termcap

En el FAQ del Terminator hay dos útiles secciones que comentan estos problemas: Why am I having problems with terminfo/curses? y Terminfo problems on Cygwin

En definitiva, el Terminator es una excelente solución para usar el Cygwin sólo localmente y sin conectarnos a sistemas externos.

Resumiendo…

Tenemos muchas formas de usar la línea de comandos del Cygwin en Windows. Las más importantes son:

  • Con el CMD de Windows
  • Tras habilitar los servidores necesarios, conectando desde cualquier cliente de SSH, Telnet o rlogin
  • Con una ventana de xterm o rxvt si el servidor X está ejecutándose
  • Con el rxvt independiente del servidor X
  • Con el PuTTYcyg
  • Con el Terminator

Y para finalizar una curiosidad: El Termcap es obra de Richard M. Stallman y la base de datos del Terminfo/Termcap es mantenida por Eric S. Raymond.

Actualización 19/1/2012: Leo que el autor del PuTTYcyg ha decidido no seguir manteniéndolo. Entre las alternativas que se comentan, está la propuesta por el propio autor de PuTTY, Simon Tatham: PuTTY wish cygwin-terminal-window. ¡Acabo de probar lo que propone y me parece incluso mejor opción que el PuTTYcyg!

:wq!

Entradas relacionadas

2 Comentarios a “Terminales para Cygwin. Notas sobre Terminfo y Termcap.”

  • Dawud Medina dice:

    Hola!
    Llevo tiempo usando Cygwin en la máquina windows del trabajo, porque me proporciona herramientas que echo de menos en estos entornos (soy usuario Linux habitual), y he estado bastante tiempo buscando cómo tener varias sesiones cygwin abiertas sin tener varias ventanas simultáneamente. La solución que encontré fue screen. Es este un magnífico programa, muy sencillo de utilizar y que permite esta funcionalidad.
    Mi problema: copiar y pegar usando el ratón pasa por desplegar el menú en la barra de la ventana: método tedioso. Xterm soluciona este problema, y ahora descubro Terminator, genial!
    Añadir, solamente, que usando Cygwin a través de Terminator, basta con iniciar screen para poder conectar a otras máquinas sin problemas de $TERM desconocida: basta con declarar xterm como nuestra consola preferida en .screenrc

    “En definitiva, el Terminator es una excelente solución para usar el Cygwin sólo localmente y sin conectarnos a sistemas externos” [SOLUCIONADO]

    Un saludo, y mucho ánimo, tu blog es genial y, personalmente, pienso que es una referencia de calidad insuperable. Gracias!

  • @Dawud Medina Muchas gracias por tu excelente aportación. Yo también uso screen de vez en cuando, ya que es una excelente herramienta. Lo que no sabía es que combinada con Terminator podemos permitirnos el conectar a otros sistemas.

    Esto es lo que se lee en el man de screen:

    In each window's environment screen opens, the $TERM variable is set to "screen" by
    default.  But when no description for "screen" is installed in the local termcap or
    terminfo  data  base, you set $TERM to - say - "vt100". This won't do much harm, as
    screen is VT100/ANSI compatible.  The use of the "term" command is discouraged  for
    non-default purpose.  That is, one may want to specify special $TERM settings (e.g.
    vt100) for the next "screen rlogin othermachine" command.

    y además lo he probado y funciona muy bien. ¡Es una información muy útil! ¡Gracias!

Tema LHYLE09, creado por Vicente Navarro