2011-04-22 19 views
5

Quiero manejar la entrada del usuario, pero en el fondo, como en un nuevo hilo.manejar la entrada del usuario en el fondo

Por ejemplo, muestran una barra de progreso, y cuando el usuario pulsa R, se restablece la barra de progreso, o si el usuario pulsa Q, el script finaliza.

No quiero que el script espere la entrada del usuario. Simplemente represente todo y, si el usuario pulsa cualquier tecla, haga algo.

¿Es posible en bash?

Gracias de antemano.

EDIT: necesito el guión SIEMPRE lea la entrada del usuario, pero no interrumpen la ejecución del principal loop.Complicated me hago entender en Inglés

_handle_keys() 
{ 
    read -sn1 a 
    test "$a" == `echo -en "\e"` || continue 
    read -sn1 a 
    test "$a" == "[" || break 
    read -sn1 a 

    case "$a" in 
     C) # Derecha 
      if [ $PALETTE_X -lt $(($COLUMNS-$PALETTE_SIZE)) ] ; then 
       PALETTE_X=$(($PALETTE_X+1)) 
      fi 
     ;; 
     D) # Izquierda 
      if [ $PALETTE_X -gt 0 ] ; then 
       PALETTE_X=$(($PALETTE_X-1)) 
      fi 
     ;; 
    esac 
} 
render() 
{ 
    clear 
    printf "\033[2;0f BALL (X:${BALL_X} | Y:${BALL_Y})" 
    _palette_render # Actualiza la paleta 
    _ball_render 
} 

while true 
do 
    LINES=`tput lines` 
    COLUMNS=`tput cols` 

    render 
    _handle_keys 
done 

En mi escritura, la bola se mueve (render>_ball_render) solo cuando se presiona una tecla porque _handle_keys espera la entrada del usuario.

Hice una solución fea con read -t0.1 pero no les gusta esta

PD: Lo siento por mi último comentario, la edición acabe el tiempo en medio de mi edición de

+0

@ user719946 es posible que necesite aclarar lo que está tratando de hacer. Los trabajos en segundo plano se suspenderán si intentan leer desde la terminal. Obtuve algunos resultados en Google para "bash non-blocking io", ¿es eso lo que intentas hacer? Además, no es necesario poner [bash] en el tema, la etiqueta es suficiente. – Andy

+0

@andy thx por su respuesta. Estoy haciendo un script como un juego de pong. El movimiento de actualización de la pelota está en un bucle principal (mientras que true lo hace). Por lo tanto, la entrada de lectura (mover la paleta) bloquea los movimientos de la pelota porque espere hasta que el usuario presione cualquier tecla. Espero que me entiendas. Lo siento por [bash] y sin nombre de usuario; esta es mi primera pregunta. – jotapdiez

Respuesta

7

Aquí es una técnica que parece trabajo. Estoy basando esto en la respuesta de Sam Hocevar al Bash: How to end infinite loop with any key pressed?.

#!/bin/bash 

if [ ! -t 0 ]; then 
    echo "This script must be run from a terminal" 
    exit 1 
fi 

stty -echo -icanon time 0 min 0 

count=0 
keypress='' 
while true; do 
    let count+=1 
    echo -ne $count'\r' 

    # This stuff goes in _handle_keys 
    read keypress 
    case $keypress in 
    # This case is for no keypress 
    "") 
    ;; 
    $'\e[C') 
    echo "derecha" 
    ;; 
    $'\e[D') 
    echo "izquierda" 
    ;; 
    # If you want to do something for unknown keys, otherwise leave this out 
    *) 
    echo "unknown input $keypress" 
    ;; 
    esac 
    # End _handle_keys 
done 

stty sane 

Si el stty sane se falta (por ejemplo, debido a que el script se mató con Ctrl - C), el terminal quedará en un estado extraño. Es posible que desee consultar la declaración trap para abordar esto.

+0

En su secuencia de comandos, el ciclo finaliza cuando se presiona una tecla. He actualizado mi primera publicación para mostrarte mi script. – jotapdiez

+0

@jotapdiez Actualicé el ejemplo. No estoy seguro de qué tan bien funcionará esto en un terminal lento, las secuencias de múltiples bytes pueden romperse. Pero esto debería estar cerca. – Andy

+0

¡Funciona! Hice algunas otras cosas para que funcione mejor, pero tu respuesta funciona bien. Gracias. (No puedo votar porque necesita más representante, lo siento) – jotapdiez

1

También puede agregar "restablecer" al final de la secuencia de comandos para restablecer el terminal en el estado original, o puede parecer bloqueado. También borrará la pantalla, por lo que es posible que desee agregar una pausa antes de ejecutar el comando.

Cuestiones relacionadas