Estoy jugando con un guión que, entre otras cosas, enumera una lista de selección. Como en:
1) Elemento 1 # (resaltado) 2) Artículo 2 3) Elemento 3 # (seleccionado) 4) Artículo 4
- Cuando el usuario presiona los
down-arrowsiguientes elementos se resalta - Cuando el usuario presiona
up-arrowlos elementos anteriores se resalta - etc.
- Cuando el usuario presiona el
tabelemento está seleccionado - Cuando el usuario presiona
shift+tabtodos los elementos están seleccionados / deseleccionados - Cuando el usuario presiona
ctrl+atodos los elementos están seleccionados - ...
Esto funciona bien a partir del uso actual, que es mi uso personal donde mi propia configuración filtra la entrada.
La pregunta es cómo hacer que esto sea confiable en varios terminales.
Yo uso una solución algo hack para leer la entrada:
while read -rsn1 k # Read one key (first byte in key press)
do
case "$k" in
[[:graph:]])
# Normal input handling
;;
$'\x09') # TAB
# Routine for selecting current item
;;
$'\x7f') # Back-Space
# Routine for back-space
;;
$'\x01') # Ctrl+A
# Routine for ctrl+a
;;
...
$'\x1b') # ESC
read -rsn1 k
[ "$k" == "" ] && return # Esc-Key
[ "$k" == "[" ] && read -rsn1 k
[ "$k" == "O" ] && read -rsn1 k
case "$k" in
A) # Up
# Routine for handling arrow-up-key
;;
B) # Down
# Routine for handling arrow-down-key
;;
...
esac
read -rsn4 -t .1 # Try to flush out other sequences ...
esac
done
Y así.
Como se mencionó, la pregunta es cómo hacer que esto sea confiable en varios terminales: es decir, qué secuencias de bytes definen una clave específica. ¿Es factible incluso en bash?
Un pensamiento era usar uno tputo infocmpy filtrar por el resultado dado por eso. Sin embargo estoy en un obstáculo que hay que tanto tputy infocmpdifieren de lo que en realidad leo cuando en realidad la pulsación de teclas. Lo mismo ocurre, por ejemplo, con C sobre bash.
for t in $(find /lib/terminfo -type f -printf "%f\n"); {
printf "%s\n" "$t:";
infocmp -L1 $t | grep -E 'key_(left|right|up|down|home|end)';
}
Las secuencias de rendimiento se leen como se define, por ejemplo linux, pero no xterm, que es lo que establece TERM.
Por ejemplo, flecha izquierda:
tput/infocmp:\x1 O Dread:\x1 [ D
¿Qué me estoy perdiendo?

dialogvariantes, o use un lenguaje conncursessoporte decente (perl o python, por ejemplo, si desea seguir con los lenguajes de "scripting").zshtiene soporte para maldiciones incorporadas (en el módulo zsh / curses) además de consultas básicas de terminfo con su matrizechotiincorporada y$terminfoasociativa.Respuestas:
Lo que falta es que la mayoría de las descripciones de terminal (
linuxes una minoría aquí, debido al uso generalizado de cadenas codificadas.inputrc) usan el modo de aplicación para teclas especiales. Eso hace que las teclas de cursor como se muestrantputyinfocmpdifieran de lo que envía su terminal (sin inicializar). las aplicaciones curses siempre inicializan el terminal, y la base de datos del terminal se usa para ese propósito.dialogtiene sus usos, pero no aborda directamente esta pregunta. Por otro lado, es engorroso (técnicamente factible , rara vez se hace ) proporcionar una solución de solo bash. Generalmente usamos otros idiomas para hacer esto.El problema con la lectura de claves especiales es que a menudo son múltiples bytes, incluidos caracteres incómodos como escapey ~. Puede hacer esto con bash, pero luego debe resolver el problema de determinar de forma portátil qué clave especial era esta.
dialogambos manejan la entrada de teclas especiales y se hacen cargo (temporalmente) de su pantalla. Si realmente quiere un programa simple de línea de comandos, no lo esdialog.Aquí hay un programa simple en C que lee una clave especial y la imprime en forma imprimible (y portátil):
Suponiendo que se llamara a esto
tgetch, lo usaría en su script de esta manera:Otras lecturas:
dialog- Widgets de maldiciones guiadas por script (aplicación y biblioteca)fuente
inputrcfue el culpable que estaba buscando. Hay que mirarlo un poco más. He considerado ir a Python o C, pero también resulta divertido piratearlo como un script bash. También intenté echar un vistazo a la fuente ncurses para ver si podía extraer los bits que necesitaba, pero después de bastante tiempo cavando la fuente, la dejé en hielo. El "proyecto" comenzó como un comando simple, luego se convirtió en un script interactivo simple y luego se extendió nuevamente. En algún lugar del camino, debería haber ido a otro idioma , pero me puse un poco terco (y como se mencionó, es divertido hackearlo en bash 2 :)/usr/share/doc/readline-common/inputrc.arrows,. Como ya tengo una función genérica "read_key" que utilizo en todo el script, esperaba que hubiera una manera más fácil de definir las secuencias (en el script) de lo que realmente se presenta cuando se presiona una tecla. Es decir, similar a extraer definiciones deinfocmp. Pero suponga que no, y que tenga que dejarlo como está o pasar a otro idioma. Un compromiso podría ser, por supuesto, usar su, agradable, C-snippet. Pero luego puedo escribir todo en C en su lugar. (Perdón por-lncurses, etc.¿Has intentado usar
dialog? Viene de manera estándar con la mayoría de las distribuciones de Linux y puede crear todo tipo de cuadros de diálogo basados en texto, incluidas las listas de verificación.Por ejemplo:
Obtendrás algo como esto:
Y la salida será:
(o los elementos que haya seleccionado).
man dialogobtendrá información sobre los otros tipos de diálogos que puede crear y cómo personalizar la apariencia.fuente
Curses,DBIyDBD::SQLitemódulos. o sus equivalentes en pitón.