A Weird Imagination

Interpreting keypresses in shell

The problem#

Last time, I presented a script read_keypress.sh which would read any single keypress in a shell script. For printable characters, it's straightforward what this means, but for keys like left arrow (🠈), it's not obvious how to deal with them.

The solution#

keytest.sh demonstrates using read_keypress.sh to respond to keypresses including 🠈 and Ctrl+c:

#!/bin/bash

esc=$(printf '\e')
ctrlc=$(printf '\x03')

while true
do
  key="$(./read_keypress.sh)"
  case $key in
    q|"$ctrlc")
      echo "Quitting..."
      exit
      ;;
    "${esc}[D")
      echo "Moved left."
      ;;
    *)
      echo "Unexpected key: $key ($(echo -n "$key" | xxd))"
      ;;
  esac
done

The details#

Read more…

Handling keypresses in shell

The problem#

For certain applications it can be useful to get many quick responses from the computer, so we would like it to react to individual keypresses instead of requiring an entire command to be typed out and confirmed by pressing Enter. While this is a common feature of GUI and TUI toolkits (e.g., ncurses), it can also be useful for very lightweight inactive experiences written as simple shell scripts.

The solution#

read_keypress.sh will wait for the next keypress and return it as a string:

#!/bin/sh

STTY=$(stty --save)
stty raw -echo
SEL=$(dd if=/dev/tty bs=1k count=1 2>/dev/null)
stty "$STTY"
echo -n "$SEL"

The details#

Read more…