Alguna vez cuando creamos un script tenemos la curiosidad (o a veces necesidad) de hacer que nuestro programa actue al presionar una tecla (alfanumerica, teclas de funcion, teclas especiales) sin que el usuario tenga que presionar despues ENTER.
En este articulo se describira una tecnica que hara que cuando el usuario presione una tecla, nuestro script ejecutara la siguiente accion dentro del script. Y cuando se menciona "una tecla", aparte de las teclas alfanumericas, tambien actuara con las teclas de funcion (F1, F2, ...).
El codigo de ejemplo que se utilizara fue probado en korn shell. Puede ser que funcione en algun otro shell sin modificaciones.
Basicamente, el truco esta en utilizar los comandos stty y dd.
Esta es la parte principal del script. Lo unico que hace es entrar en un ciclo hasta que el usuario presione la letra q (minuscula).
A la variable tecla se le asigna el valor que devuelve la funcion leerTecla. Esa es la encargada de leer las teclas que presiona el usuario.
Como vamos a cambiar la configuracion de stty, dentro de esta funcion se guarda primero la configuracion actual de stty en la variable sttyAnt. Despues, con el comando dd leemos un caracter de la entrada estandar y lo guardamos en la variable final. Despues enviamos esta variable como parametro a la funcion teclaEspecial que se encarga de regresar una cadena con el nombre de la tecla que se presiono (ENTER, ESC, CTRL_E, etc.).
En algunos casos, cuando presionamos alguna tecla (como las teclas de funcion), al teclado se envian varios caracteres. Comunmente estas teclas "compuestas" envian primero el caracter ESC seguido de otro caracter. Por esto, dentro de la funcion se verifica si la tecla que se leyo fue ESC. Si fue asi entonces leemos otra tecla. Si la siguiente tecla que se leyo no es corchete, entonces simplemente concatenamos ESC mas la tecla que se leyo. Si fuera un corchete, entonces tendriamos que leer otro caracter y lo concatenamos a ESC[.
Al final de la funcion se vuelven a los valores originales que habiamos guardado con el comando stty $sttyAnt. Y por ultimo regresamos la cadena que indica la(s) tecla(s) que leimos.
La funcion teclaEspecial se encarga de regresar el "nombre" de la tecla que se presiono.
El parametro -z dentro del IF devuelve verdadero si la cadena esta vacia. Asi, en el primer IF, verificamos si el parametro esta vacio. De ser asi, suponemos que el usuario presiono ENTER.
En los demas IFs, lo que se hace es un echo del parametro que recibio la funcion y eliminamos (con el comando tr -d) ciertos caracteres. Por ejemplo, para saber si se presiono ESC, hacemos
El codigo de la tecla ESC es 27 (o \033 en el sistema octal). Asi, despues de eliminar el caracter \033, si la cadena esta vacia, significa que se presiono ESC.
En el ejemplo solo se muestran algunas teclas especiales. Agregando mas condiciones podremos hacer que se procesen las que podamos necesitar.