Search code examples
linuxbashkeyboarddelaywait

How to handle a long press on button in a waitkey function of bash script?


I am implementing a "waitkey" function in bash script, which waits for user to press a button on keyboard to continue.

However, since different people have different pressing habits, when people press a button for a long time, my script always treat this long press as multiple separate presses.

waitkey() {
   read -n 1 -s -r -p "Press any key to continue"
}

Is it possible to modify my code in this way: For the interval between 2 separate clicks must be longer than 2 seconds, so that if one presses the button for 1.5 seconds, this long pressing will not be treated as two separate clicks.


Solution

  • Edit: This SuperUser answer may help you with clearing the input before your wait for a key press: https://superuser.com/a/622205

    To do what you want, you would either have to:

    • Disable key repeat before reading user input.

    or

    • Detect a KeyUp event before accepting a new input.

    Short answer: this is not possible within a Shell.

    Long answer: this is mostly impossible and surely not portable.

    There is no mean to process keydown and keyup events in any unix tty console environment and so not in Bash, because of the way consoles and terminals works.

    The terminal tty device only deals with characters streams.

    Doing what you ask for with your script require low level access to the keyboard device.

    There are means to do it locally, but it is absolutely not trivial, rely on the X-Window protocol or local and privileged accesses to the keyboard device.

    I found this detailed blog post you can read if you want to know more why it is so hard to detect KeyUp events on Linux:

    https://blog.robertelder.org/detect-keyup-event-linux-terminal/