Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

handle user input on background

I want to handle user input, but in the background, like in a new thread.

For example, show a progress bar, and when the user hits R, the progress bar resets, or if the user hits Q, the script exits.

I don't want the script to wait for user input. Just render everything and if the user hits any key do something.

Is it posible in bash?

Thanks in advance.

EDIT: I need the script ALWAYS read user input but do not interrupt the execution of main loop.Complicated I make myself understood in English

_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

In my script, the ball moves (render>_ball_render) only when a key is pressed because _handle_keys wait for user input.

I made a ugly solution with read -t0.1 but don't like this

PD: Sorry for my last comment, the time edit finish in the middle of my editing

like image 398
jotapdiez Avatar asked Apr 22 '11 02:04

jotapdiez


People also ask

How to handle user input in MVC?

Another way to handle user input is polling, or periodically checking the state of the hardware. The original Smalltalk MVC used this approach, and it’s still used in game programming. 1 I don’t think I’ve ever written any code that used polling for handling user input, so I wanted to at least give it a try.

How do you handle user input in a drag handler?

The body of handler should be guarded with , just like the handler. Otherwise (1) a drag that starts the square, but ends over it, is treated as a click; and (2) after cancelling a drag, the next event sets the status to . Another way to handle user input is polling, or periodically checking the state of the hardware.

What are the keyboard events that my control can handle?

Handling keyboard input is considerably more complex than overriding the events in the preceding table and is beyond the scope of this topic. For more information, see User Input in Windows Forms. The mouse events that your control can handle are MouseDown, MouseEnter, MouseHover, MouseLeave, MouseMove, and MouseUp.

Why don’t you trust user input in C?

Don’t Trust User Input. In C when you not limited the user input and the user input larger than the container, the input filled up your container and also fill another container. It is also called Buffer Overflow. The key for handle the user input, limited the user input same with you define the container for that input.


2 Answers

Here is a technique that seems to work. I am basing this on Sam Hocevar's answer to 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

If the stty sane is missed (e.g. because the script gets killed with Ctrl-C), the terminal will be left in a weird state. You may want to look at the trap statement to address this.

like image 120
Andy Avatar answered Sep 28 '22 23:09

Andy


You might also add "reset" to the end of the script to reset the terminal into original state, or it might look locked. It will clear the screen as well, so one might want to add a pause before executing the command.

like image 33
Rado Avatar answered Sep 28 '22 21:09

Rado