Esta página puede ser redistribuida libremente bajo los términos de la licencia GPL. Vease ( GPL texto original ) o si lo prefiere (Traducción española no oficial de la GPL) Al margen de las obligaciones legales que se derivan del uso de esta licencia rogamos sea respetada la referencia a su lugar de publicación original www.ciberdroide.com. y a su autor original Antonio Castro Snurmacher (Madrid 01/01/2000).

Ausencia de Garantía

Esta ausencia de garantía se hace extensa a cualquier tipo de uso de este material y muy especialmente a las prácticas, ejercicios, y de ejemplos que encuentre en estas páginas. Deberá trabajar siempre salvo indicación contraria con un SO Linux y con un usario distinto de 'root' sin privilegios especiales. Como directorio de trabajo se procurará usar el directorio '/tmp' o algún otro que no contenga información valiosa. Tampoco se considera buena idea practicar en una máquina que contenga información valiosa.

Todo esto son recomendaciones de prudencia. En cualquier caso si algo sale mal toda la responsabilidad será únicamente suya. En ningún caso podrá reclamar a nadie por daños y perjuicios derivados del uso de este material. Para más información lea el contenido de la licencia GPL y abstengase de hacer prácticas si no está dispuesto a asumir toda la responsabilidad.

Terminales

Que es un terminal.
En Linux y otros SO similares se considera la posibilidad de que un ordenador tenga varios usuarios trabajando simultáneamente.

Cada dispositivo que permite a un usuario interactuar con una máquina se le llama terminal. Hay terminales de entrada como por ejemplo un lector de código de barras, los ya obsoletos lectores de tarjetas perforadas, terminales salida como por ejemplo una impresora, y terminales de entrada salida como los clásicos terminales de pantalla.

Hay otras muchas clases de terminales. Por ejemplo hay terminales para personas ciegas, pero el tipo más utilizado es el formado por pantalla y teclado. Dentro de esta categoría hay cientos de modelos distintos. En Linux y en otros SO tipo Unix se contempla la posibilidad de trabajar casi con cualquier tipo de terminal.

La palabra tty usada para designar los dispositivos que controlan los terminales viene de TeleTYpe (teletipo). Los primeros terminales no tenían monitor. Eran simples y primitivos teletipos.

En un PC la pantalla y el teclado son periféricos que se conectan de forma independiente al ordenador, pero en ordenadores grandes los terminales de pantalla y teclado son un todo que se comunica con el ordenador por un único cable. Por ejemplo a través de un puerto serie. Por estos cables lo que circulan bytes correspondientes a los caracteres intercambiados entre el terminal y el ordenador. Antes de que surgieran los ordenadores personales lo normal era que el ordenador estuviera en un cuarto cercano a la sala de terminales donde los usuarios se sentaban a trabajar.

Podemos ver en la figura un conjunto formado por oordenador central y una serie de ordenadores conectados a él.

Estos terminales que acabamos de mencionar aun se usan hoy en día y no son simples conjuntos de teclado y monitor. Tienen cierto grado de autonomía lo cual permite liberar al ordenador central de una parte del trabajo ya que en lugar de atender las entradas tecla a tecla, lo hará línea a línea. La pantalla de un terminal no es simplemente un monitor ya que su electrónica es más compleja. Entre sus circuitos electrónicos dispone de una memoria. Esta guarda la información hasta tener la línea completa que además puede ser editada sin que en eso intervenga el ordenador. La pantalla en cambio muestra los caracteres tecleados a medida que se van introduciendo. Por eso lo que vemos en el terminal quizás no ha sido transmitido aún al ordenador. En realidad la memoria del terminal contendrá no solo el buffer del teclado sino todo el contenido de la pantalla del terminal. Esto es necesario por varias razones. Una de ellas es la posibilidad de hacer scroll vertical y otra para recuperar la información de toda la pantalla en caso necesario.

Terminales virtuales
Si ha pasado lo anterior por alto pensando que no tiene que ver con su caso por trabajar con PCs, vuelva a leer los párrafos anteriores porque en un PC que use Linux una sesión de consola como las que estamos usando en este curso, funcionará de forma muy similar por ser una simulación de este tipo de terminales.

En Linux existe una emulación de varios terminales sobre un único monitor. Se denominan frecuentemente terminales virtuales. Para cambiar de un terminal virtual a otro pulsaremos <Alt><F1>, <Alt><F2>, <Alt><F3>, etc. Con ello tendremos acceso a los terminales /dev/tty1, /dev/tty2, /dev/tty3, etc respectivamente. En cada uno de estos terminales puede mantenerse una sesión de trabajo distinta.

Es como si tuviéramos varios terminales físicos distintos formados por monitor, teclado, altavoz, memoria, y cable de conexión al ordenador, pero solo pudiéramos usar uno de ellos en un momento dado. La información de cada terminal virtual se encuentra almacenada en dispositivos /dev/vcs pero no es accesible para usuarios normalitos.

Dispositivos controladores de terminales
Cada terminal virtual está gestionado por un controlador de dispositivo. Si ejecuta el comando 'tty' obtendrá el nombre del controlador que está usando.

$ tty
 /dev/tty3

Bueno /dev/tty3 sería el nombre del terminal. Usted puede obtener otra cosa pero vamos a suponer que su terminal fuera este.

$ echo "hola" > /dev/tty3 

Sacará el mensaje "hola" en la pantalla de su terminal. Si intenta hacer esto mismo sobre otro dispositivo, por ejemplo /dev/tty2 debería aparecer el mensaje en la pantalla de otro terminal. Normalmente esto no sucede a no ser que /dev/tty2 también esté funcionando con su usuario. Con esto se evita que un usuario pueda molestar a otro.

Los terminales virtuales están numerados del 0 al 63. Para ver cual es el número del terminal actual también se puede usar 'fgconsole'

Hay otros tipos de terminales. Son dispositivos de tipo carácter y hay un montón de ellos disponibles.

$ ls /dev/*tty*

Existe un dispositivo especial que para cada usuario se comporta como si fuera su propio controlador.

$ echo "hola" > /dev/tty 

Esto saca un mensaje en la pantalla de su propio terminal exactamente igual que el el caso anterior. Esto puede ser útil para usarlo por ejemplo en scripts que pueden tener ambas salidas (estándar y de errores) redirigidas a ficheros pero deseamos que determinado mensaje salga siempre por la pantalla.

Existe otro dispositivo especial llamado consola /dev/console. Este dispositivo suele encontrarse próximo a la máquina y por el salen los mensajes del sistema. Se asume que este puesto de trabajo es usado por el administrador del sistema.

La consola está asociada a /dev/tty0 que al igual que /dev/tty es un alias de terminal virtual actual pero pueden tener permisos distintos.

Vamos a hacer algunas pruebas y vamos a suponer que su sesión de trabajo con bash utiliza el tty3. Compruebe cual es su caso con el comando 'tty' y en caso de ser distinta téngalo en cuenta cada vez que hagamos referencia al tty3 o a <Alt><F3>. Usted deberá usar lo que corresponda en su caso. También puede pasarse al tty3 para continuar la lección.

Primero vamos a comprobar la disponibilidad y los permisos de un tty que casi siempre queda libre. El tty12.

$ ls -l /dev/tty12
 crw-rw-rw-  1 root   tty      4, 12 ago 29  2000 /dev/tty12

Aquí lo importante es comprobar que podemos usar ese terminal y que tiene permisos de lectura escritura.

Si esto no es así habría que modificar los permisos o incluso crear el dispositivo para poder hacer la práctica pero eso requiere privilegios de root y nos saldríamos de los propósitos de este curso.

Vamos a probar si podemos escribir en el tty12.

Si usted hace 'echo xxxxx > /dev/tty12' y luego pasa al terminal tty12 con <Alt><F12> verá que no puede hacer nada en él pero las 'xxxxx' aparecen en la pantalla.

Vamos a probar si podemos leer del tty12.

Haga 'cat < /dev/tty12' desde su sesión de trabajo y luego pase al terminal tty12 con <Alt><F12> e introduzca una cadena sin usar la tecla <Intro>. Por ejemplo 'yyyyyyyyyyyy'.

Si vuelve al tty3 con <Alt><F3> comprobará que el comando cat continua esperando recibir datos pero aun no ha recibido ningún carácter. La razón es que la cadena 'yyyyyyyyyyyy' se encuentra todavía en la memoria del terminal tty12 y todavía no se ha enviado un solo carácter al ordenador.

El modo normal de funcionamiento de los terminales de texto es este. En lugar de enviar caracteres aislados envían chorros de caracteres.

Vuela al tty12 con <Alt><F12> y pulse <Intro>. Inmediatamente vuelva a tty3 con <Alt><F3> y comprobará que cat acaba de recibir la cadena de caracteres. Para finalizar cat interrúmpalo con <Ctrl+C>.

Si alguna de estas dos pruebas de lectura o escritura no ha funcionado posiblemente se deba a unos permisos demasiado restrictivos o a una diferente configuración en su equipo y eso supone que tendrá dificultades para practicar esta lección pero nosotros vamos a ir explicando todo lo que sucede en cada práctica.

Sesión de trabajo en un terminal (getty)
Repasemos un poco cosas que ya comentamos en lecciones anteriores. Hay un fichero de configuración '/etc/inittab' que durante el arranque activará un programa llamado 'getty'. Este mandará un mensaje a la consola en espera de que alguien introduzca su nombre de usuario. Cuando esto sucede 'getty' hace un exec al programa 'login' con el nombre de usuario obtenido y login solicitará la password. Si la password es correcta login hará un exec a la shell.

Esto ya lo vimos cuando hablamos de los procesos y si recuerda 'exec' es una llamada al sistema que cambia el código del programa que se está ejecutando sin cambiar su PID. Cuando la shell termine, el proceso 'init' detectará la muerte de su proceso hijo y arrancará un nuevo 'getty' porque en '/etc/inittab' estos procesos figuran en modo respawn. También figura el nombre del dispositivo y la velocidad de comunicación.

Los terminales que no tengan entrada en este fichero /etc/inittab no estarán disponibles para una sesión de trabajo en modo consola pero eso no quiere decir que sean inútiles. Por ejemplo si en /etc/inittab solo aparecen los terminales que van desde tty1 a tty6 solo podrá abrir estos seis terminales virtuales pero si se arrancan las Xwindows lo harán en el primer terminal disponible que en este caso será el tty7.

Este es un curso de usuario y a pesar de que a estas alturas del curso se explican cosas algo avanzadas no pretendemos enseñarle a administrar el sistema. En particular le advertimos que no debe intentar modificar /etc/inittab aunque disponga de cuenta de root si no sabe exactamente lo que está haciendo, porque su sistema podría no volver a arrancar.

'getty' es un programa normal que no requiere privilegios especiales para ser ejecutado.

La práctica que ponemos ahora solo será posible si su puesto de trabajo es un PC con Linux. Si está trabajando en un terminal independiente del ordenador central no podrá hacerlo. Si la prueba de enviar 'xxxxx' al terminal tty12 no fue satisfactoria tampoco podrá hacer esta otra prueba.

Localice getty con el comando locate por ejemplo. Supongamos que lo encuentra en '/sbin/getty'.

Mire en /etc/inittab la parte donde aparece getty.

$ cat /etc/inittab

#  <id>:<runlevels>:<action>:<process>
1:2345:respawn:/sbin/getty 38400 tty1
2:23:respawn:/sbin/getty 38400 tty2
3:23:respawn:/sbin/getty 38400 tty3
4:23:respawn:/sbin/getty 38400 tty4
5:23:respawn:/sbin/getty 38400 tty5
6:23:respawn:/sbin/getty 38400 tty6

Supongamos que figura lo que acabamos de poner. respawn es la acción realizada por init. Significa en este caso ejecutar y volver a ejecutar cada vez que termine. /sbin/getty es el programa que abrirá el terminal. El primer parámetro después de getty es la velocidad de transmisión (en este caso 38400), y el último parámetro es el terminal.

Nos basamos en esta información para lanzar getty sobre el tty12:

/sbin/getty 38400 tty12

Comprobará que aparentemente el programa no termina. Pase ahora al terminal tty12 con <Alt><F12>

Verá que 'getty' ha abierto una sesión en ese terminal. 'getty' esta funcionando sin ningún problema. Introduzca su nombre de usuario y verá que login no es tan permisivo. Dará un mensaje de error no reconociendo a su padre como un padre legítimo. Para evitar usos extraños de login se termina su ejecución. Volviendo a la sesión donde arranco getty verá que este también terminó.

Este intento fracasado no quiere decir que no se pueda abrir una sesión de trabajo en una consola que no esté controlada por 'getty'. Solo significa que 'login' es un vigilante celoso de la seguridad del sistema, y hemos intentado usarlo de una manera no convencional.

No solo se puede abrir una sesión de trabajo en una consola que no esté controlada por 'getty' sino que además es muy fácil y no requiere permisos especiales. Para abrir una sesión en el /dev/tty12 basta con ejecutar 'openvt -c 12 bash' y esto lo comentamos simplemente como curiosidad para que lo pruebe si quiere pero no merece más explicación en este momento.

Toda esta práctica un poco rara pretende que comprenda como funcionan las cosas. El tema de los terminales es bastante amplio.

La librería ncurses
No vamos a aprender a usar estas librerías porque este no es un curso de programación pero es una librería muy importante y encontrará montones de referencias en el manual de Linux a estas páginas. Resulta imprescindible comentar algo de ncurses para comprender el comportamiento de algunas aplicaciones.

Ya hemos dicho que hay muchas clases de terminales y que incluso un determinado tipo de terminal físico puede funcionar de formas distintas, emulando unos terminales a otros. Cada terminal tiene su propio lenguaje de comandos que no son otra cosas de secuencias de caracteres asociadas a determinadas acciones. Por ello una aplicación debe conocer con que terminal está tratando.

Las aplicaciones hacen esto usando una librería intermedia que se encargará de traducir cada acción a la secuencia de caracteres adecuada. Esta librería se llama 'curses' o su versión moderna llamada 'ncurses'. La aplicación debe de ser informada de el tipo del terminal con el cual está trabajando y eso se hace a través de la variable TERM.

Si usted consulta (hágalo) el valor de esta variable seguramente obtendrá 'linux' que es el nombre del terminal que linux usa por defecto. Hay muchos tipos de terminales y cada uno tiene su nombre. Por ejemplo si usted ejecuta TERM='vt100'; export TERM; La aplicación que se ejecute a continuación puede pensar que tiene que dialogar con un terminal tipo 'vt100'.

Bueno algunas aplicaciones no hacen esto. Directamente asumen que funcionarán en un determinado tipo de terminal y por ello no usan ni la variable TERM ni la librería curses. Por ejemplo ls --color=auto asumirá siempre que el terminal es un terminal 'linux' y enviará directamente las secuencias de caracteres apropiadas para un terminal 'linux' aunque existe un fichero de configuración más que nada para poder poner el color que uno quiera a cada cosa. Puede probar a cambiar la variable TERM y comprobará que los colores salen perfectamente.

Por el contrario la utilidad 'less' si usa 'ncurses' úsela poniendo la variable TERM=att4424 y comprobará que la aplicación se comporta de un modo extraño. En cambio si usa la variable TERM=vt100. Se comportará de forma casi normal porque el terminal 'vt100' y el terminal 'linux' tienen algunas similitudes. En realidad vt100 (DEC) es un tipo de terminal muy conocido, y el terminal de linux deriva de él.

Hemos elegido 'ls' y 'less' porque no suponen un peligro en caso de uso incorrecto pero si intenta hacer esto con otro programa como por ejemplo un editor podría destruir un fichero debido al desconcierto organizado en su pantalla.

La librería curses accede a una base de datos de terminales (terminfo) donde se establecen la capacidades de cada terminal.

Si usted está trabajando con linux en un terminal que no es de tipo 'linux' notará que algunas aplicaciones no van bien. La forma de arreglarlo es cambiar la variable TERM con el valor apropiado a su terminal y así por lo menos las aplicaciones que usen curses volverán a funcionar perfectamente.

El terminal de linux
Las capacidades del terminal de linux son muy variadas. Manejo del cursor, borrado de partes o de la totalidad de la pantalla, colores y otros atributos, pitido del terminal, configuración de la pantalla en filas y columnas, guardar posición del cursor, etc.. Las páginas del manual anteriormente mencionadas tratan de todo esto y la cantidad de posibilidades es tan grande que nos limitaremos a poner algunos ejemplos.

Para conocer el juego de caracteres completo y caracteres de control que tiene un terminal linux consulte en la sección 7 del manual las páginas de ascii(7) e iso_8859_1(7). Para una relación de las secuencias de control consulte la página console_codes(4).

Antes que nada conviene saber que el terminal puede quedar en un estado que resulte muy difícil de usar. Si eso llega a ocurrir teclee '<Intro>reset<Intro>' y con un poco de suerte todo volverá a la normalidad. Pruebe ahora este comando para asegurarse de que dispone de el antes de hacer la prueba siguiente.

$ reset

Erase is delete.
Kill is control-U (^U).
Interrupt is control-C (^C).

Se muestra la configuración por defecto de algunos parámetros que luego explicaremos cuando hablemos de stty.

Vamos a hacer una prueba algo delicada. Vamos a enviar un carácter de control al terminal que lo dejará en un estado bastante lamentable para trabajar con él, para ver como se puede recuperar una situación de este tipo.

Vamos a enviar un <Ctrl+N> pero para ello hay que usar una secuencia de escape idéntica a la que se vio en el capítulo del editor 'vim'. Concretamente la secuencia para introducir el <Ctrl+N>, será <Ctrl+V><Ctrl+N>. Esto aparecerá como ^N. Antes que nada cámbiese al directorio '/tmp' donde no podremos hacer muchos destrozos. Después de enviar el '^N' al terminal no podremos ver lo que hacemos porque saldrán caracteres semi gráficos en lugar de letras.

$ cd /tmp
$ echo '^N''
$FIN

Ahora olvide se del monitor por un momento y haga <Intro>reset<Intro>. Se supone que habrá funcionado bien. En caso contrario no se aceptan reclamaciones. Dispone usted de otros terminales virtuales en otros ttys así que si un terminal no se recupera puede usar otros. Conviene que aprenda a recuperar estas situaciones.

Vamos a hacer un programita que usa las secuencias de escape del terminal de linux. La explicación la puede consultar en console_codes(4).

Edite un fichero que llamaremos 'pru_console_codes.bash'.

function muestra(){
	# echo -e "\033[${POSY};${POSX}H" # Manda el cursor a $POSY $POSX
	let POSY=POSY+1 ; echo -e "\033[${POSY};${POSX}H\c" 
	echo -e '\033[30mNegro\c'
	let POSY=POSY+1 ; echo -e "\033[${POSY};${POSX}H\c" 
	echo -e '\033[31mRojo\c'
	let POSY=POSY+1 ; echo -e "\033[${POSY};${POSX}H\c" 
	echo -e '\033[32mVerde\c'
	let POSY=POSY+1 ; echo -e "\033[${POSY};${POSX}H\c" 
	echo -e '\033[33mMarron\c'
	let POSY=POSY+1 ; echo -e "\033[${POSY};${POSX}H\c" 
	echo -e '\033[34mAzul\c'
	let POSY=POSY+1 ; echo -e "\033[${POSY};${POSX}H\c" 
	echo -e '\033[35mRosa\c'
	let POSY=POSY+1 ; echo -e "\033[${POSY};${POSX}H\c" 
	echo -e '\033[36mCeleste\c'
	let POSY=POSY+1 ; echo -e "\033[${POSY};${POSX}H\c" 
	echo -e '\033[37mBlanco\c'
}

typeset -i POSY ; typeset -i POSX
echo -e '\033[2J\c' # Borrar pantalla

echo -e '\033[1m\c' # Atributo Brillo
POSY=1 ; POSX=16 ; echo -e "\033[${POSY};${POSX}H\c"
echo -e '*Brillo*\c'; muestra

echo -e '\033[2m\c' # Atributo Semi brillo
POSY=1 ; POSX=31 ; echo -e "\033[${POSY};${POSX}H\c"
echo -e '*Semi Brillo*\c'; muestra

echo -e '\033[0m\c' # Atributo normal
echo -e '\033[5m\c' # Atributo Intermitente
POSY=1 ; POSX=46 ; echo -e "\033[${POSY};${POSX}H\c"
echo -e '*Intermitente*\c'; muestra

echo -e '\033[0m\c' # Atributo normal
echo -e '\033[7m\c' # Atributo Inverso
POSY=1 ; POSX=61 ; echo -e "\033[${POSY};${POSX}H\c"
echo -e '*Inverso\c'; muestra

echo -e '\033[0m\c' # Atributo normal
POSY=1 ; POSX=1 ; echo -e "\033[${POSY};${POSX}H\c"
echo -e '*Normal*\c'; muestra 

echo -e '\033[5m\c' # Atributo intermitente
echo -e '\033[7m\c' # Atributo Inverso
POSY=12 ; POSX=1 ; echo -e "\033[${POSY};${POSX}H\c"
echo -e '*Inverso+Intermitente\c'; muestra

echo -e '\033[0m\c' # Atributo normal
echo -e '\033[5m\c' # Atributo intermitente
echo -e '\033[1m\c' # Atributo brillo
POSY=12 ; POSX=26 ; echo -e "\033[${POSY};${POSX}H\c"
echo -e '*Brillo+Intermitente\c'; muestra

echo -e '\033[0m\c' # Atributo normal
echo -e "\033[25;1H\c"

El programa termina poniendo el atributo normal pero recuerde que si algo sale mal y el terminal queda en un estado poco operativo deberá recuperarlo con el comando reset. Una vez dicho esto ponga permiso de ejecución a este fichero y ejecutelo.

Podrá comprobar como sale la información con distintos colores y atributos. Para ello hemos usado secuencias de caracteres especificas de los terminales linux y que podrían no funcionar en otros terminales.

Control de un terminal (setterm)
Para cambiar los atributos de un terminal cualquiera se usa setterm(1) que utilizará la variable TERM para identificar el terminal y usar las secuencias de caracteres adecuadas.

setterm admite el nombre de un terminal para enviar los códigos de control a ese terminal en lugar de enviarlos al terminal actual.

Vamos a cambiar el sonido del pitido de nuestro terminal.

$ setterm -bfreq 100 -blength 500

Ahora tendremos un pitido más grave de lo normal de medio segundo. Antes de volverlo a su situación normal cambie a otro terminal y compruebe que el cambio de sonido no ha tenido efecto sobre ese terminal. No piense que su ordenador tiene un único altavoz porque es como si existiera un altavoz para cada terminal solo que no puede funcionar mas que uno de ellos en un momento dado. En eso consiste la emulación de los terminales virtuales. Es un solo terminal físico pero se comporta como varios.

Para dejar el sonido como al principio haremos lo siguiente:

$ setterm -reset

Ahora vamos hacer un programa que sacará distintos sonidos.

sound(){
	setterm -bfreq $1 -blength $2
	echo -e '\a\c' > /dev/console
}

sound 2000 900
sleep 1
sound 700 400
sleep 1
sound 150 300
sleep 1
sound 70 200
sleep 1
sound 40 1000
sleep 1
setterm -reset # Volver a la situación normal
echo -e '\a\c' > /dev/console

setterm -cursor off setterm -cursor on setterm -repeat on

Configuración de un terminal (stty)
El programa stty(1) sirve para comprobar o alterar el estado de un terminal.

$ stty

speed 38400 baud; line = 0;
-brkint ixoff -imaxbel
-iexten

Esto solo muestra los parámetros más importantes. Para mostrar la totalidad de los parámetros que controlan nuestro terminal haremos

$ stty -a

speed 38400 baud; rows 25; columns 80; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <no definido>;
eol2 = <no definido>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R;
werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0;
-parenb -parodd cs8 hupcl -cstopb cread -clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon ixoff
-iuclc -ixany -imaxbel
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon -iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt
echoctl echoke

Cuando ejecutamos reset nos muestra la configuración de los siguientes tres parámetros. ( erase = ^? , kill = ^U , intr = ^C ) que son respectivamente el caracter que el terminal interpretará como el caracter para borrar el último caracter tecleado, el caracter para borrar la línea actual, y el caracter para mandar una señal de interrupción.

En la página man stty(1) viene la interpretación de todos los parámetros usados para configurar un terminal, Lo normal es que su valor permita un uso normal del terminal y por ello tocarlos podría afectar a la operatividad del terminal.

stty también permite guardar la configuración actual de un terminal en un fichero con la opción -g en un formato que permitirá al propio stty ajustar todos los parámetros de un terminal usando uno de estos ficheros generados con la opción -g.

En la prática que sigue debe recordar de para introducir un caracter de control deberá venir precedido de <Ctrl+V>

$ # Guardamos la configuración 
$ stty -g > /tmp/stty.out
$ cat /tmp/stty.out
 1500:5:4bf:a3b:3:1c:7f:15:4:0:1:0:11:13:1a:
0:12:f:17:16:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0
$ stty werase ^A # Ojo usar <Ctrl+V> <Ctrl+A>
$ stty -a
$ # Comprobamos que ahora werase = ^A; 
 speed 38400 baud; rows 25; columns 80; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = ;
eol2 = ; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R;
werase = ^A; lnext = ^V; flush = ^O; min = 1; time = 0;
-parenb -parodd cs8 hupcl -cstopb cread -clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon ixoff
-iuclc -ixany -imaxbel
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon -iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt
echoctl echoke
$ stty `cat /tmp/stty.out` # Recuperamos la configuración anterior

Los resultados de esta práctica pueden variar de un sistema a otro. Lo importante es que compruebe como hemos salvado la configuración a un fichero antes de alterar la configuración del terminal y como podemos recuperar esa configuración desde ese fichero. Usamos solo werase para ello y no vamos a proponer más ejercicios sobre esto. Los terminales en Linux no emulan siempre a la perfección a los terminales tradicionales. Lo explicamos en el siguiente apartado (ver readline).

La librería readline
Nuevamente tenemos que comentar la existencia y propósito de una librería especial no para aprender a manejarla sino para comprender una situación bastante especial de los terminales en Linux. Los terminales virtuales en Linux no se comportan como los terminales otros sistemas tipo Unix. Por ejemplo podemos cambiar el caracter de control de 'erase' con stty y parecerá que no tiene ningún efecto, cosa que se contradice totalmente con lo que dijimos antes. Esto se debe a que muchos programas de linux usan la librería 'readline' que tiene sus propias funciones de edición de linea etc.. y actúan sobreescribiendo las funciones del terminal. Esto determina dos tipos de usos distintos del terminal y dos comportamientos distintos.

Es como si existieran dos clases de dispositivos. Uno sería tty y el otro lo podríamos llamar tty->readline.

No es cuestión de profundizar en estos temas que son más adecuados para un curso de administración o de programación. Con esto se pretende simplemente dar una explicación lógica a este tipo de comportamiento muy específico de los terminales Linux.

Terminales y pseudoterminales
Ya hemos visto como puede dirigirse entrada salida a un terminal pero un proceso puede tener previsto dos comportamientos distintos para el caso que su salida está conectada a un terminal o a un fichero. Por ejemplo la opción '--color=auto' para 'ls' resulta muy útil ya que producirá dos tipos de salidas distintos dependiendo de que esté conectada bien a un terminal bien a otra cosa tipo fichero pipe etc... En el caso de estar conectado a un terminal, sacará la información en color, pero si detecta otra cosa sacará la información sin color para evitar volcar un montón de caracteres de extraños. En otras palabras 'ls' y muchos otros programas pueden averiguar si sus descriptores de entrada salida estándar están conectado o no a un terminal. La salida a un terminal determina un uso interactivo con una persona y por ello los programas se adaptan a ello. Algunas veces queremos que el comportamiento de un programa sea como si estuviera conectado a un terminal pese a que no sea cierto y porv ello algunas veces hay que usar un terminal ficticio o pseudoterminal.

Un pseudoterminal es un componente software destinado a simular un terminal. Se implementan usando una pareja de dispositivos especiales y distintos denominados esclavo y maestro. Un proceso que use un pseudoterminal pensará que está conectado a un terminal auténtico y no notará diferencia alguna.

Por ejemplo una ventana de 'xterm' en windows funciona de esa manera.

Un ejemplo de pseudoterminal (script)
Scrip es un comando que funciona creando un pseudoterminal y arrancando una subshell que no notará que la entrada salida no es un autentico terminal. Script se usa para grabar una sesión completa de trabajo con bash en un fichero si se termina al finalizar la ejecución de la shell con exit.

Pruebe lo siguiente:

$ script /tmp/script.out
$ ls --color=auto /

$ ls --color=auto / > /tmp/ls.out
$ exit

El primer 'ls --color=auto /' mostrará el contenido del directorio raíz en colores. El segundo 'ls --color=auto / > /tmp/ls.out' guardará la salida en un fichero '/tmp/ls.out'. La sesión de script se finaliza abandonando la shell con exit. Cuando miremos el contenido de '/tmp/ls.out' con el editor 'vi' comprobaremos que no hay colores ni caracteres extraños. Si miramos la sesión completa grabada con script en el fichero '/tmp/script.out' con 'vi comprobaremos que está llena de caracteres extraños. Los retornos de carro aparecen como '^M' (representa <Ctrl+M> y los códigos de colores con secuencias del tipo '^[[0m...' o similares que responden a las secuencias de control para modificar atributos y colores en la pantalla según se describe en la página console_codes(4). Si envía el contenido de este fichero a pantalla por ejemplo usando 'cat /tmp/script.out' aparecerán los colores.

script captura absolutamente todo y por ello grabar una sesión con script en un fichero puede requerir un tratamiento de filtrar ciertas cosas antes de darle determinado uso a esa salida, pero resulta muy útil si solo deseamos registrar una sesión de trabajo para no tener que ir apuntando lo que vamos haciendo o lo que vamos obteniendo.

Test
Puede comprobar sus conocimientos respondiendo el siguiente test.
Para ello seleccione las opciones que se ajusten a la verdad y luego pulse el boton para ver el resultado de su test.

1 La librería ncurses está formada por un conjunto de funciones para la edición de una línea.
2 El terminal de linux usa unas secuencias de control similares a la del terminal att4424
3 La librería ncurses permite que una aplicacion pueda funcionar en distintos tipos de terminales.
4 Para averiguar la configuración actual de un terminal usaremos getty.
5 Un pseudoterminal es un tipo de dispositivo.
6 Script abre un pseudo terminal para poder capturar una sesión de trabajo y guardarla en un fichero.
7 El comando reset apaga o reinicia todo el sistema.

Resultado del test

Si quiere hacernos llegar alguna duda, aclaración,
crítica, o contribución personal, utilice nuestro
formulario de contacto y nosotros le contestaremos
contacto