In bash I want to read a key input from user and wait even after key was pressed. I use
read -n 1 -s -t 0.05 key
but after input it stops waiting. I want to wait 0.05 no matter what and store first key pressed in variable key.
As pointed out in the comments, use sleep
. Everything entered during sleep
will be printed on the terminal (as for every command that doesn't consume stdin). Use stty
to hide this output.
stty -echo
disables output.stty echo
enables output (unconsumed characters hidden so far will be printed).You probably want to wait only the remaining time and not an additional 0.05 seconds. There are two ways to do so:
Use sleep
before read
— that way you neither have to measure the wait time nor have to compute the remaining time:
stty -echo
sleep 0.049
read -n1 -s -t0.001 key;
stty echo;
echo "key was $key"
The timeout read -t…
must be long enough to actually read the buffered characters. You can test this by copy-pasting a very long line into your terminal – read
will only read a part of it. On a slow system you may have to increase 0.001
. But keep in mind that the combined waiting time for the user can be just the sleep time, that is, a bigger -t
means less precision.
To circumvent that problem you can put sleep
after read
and compute the remaining waiting time, which of course is more work. Here is a solution in bash
5.0 or higher:
# all variables of the form tSomething are in μs = 10^-6 s
stty -echo
tStart="${EPOCHREALTIME/./}"
read -n1 -s -t0.05 key;
tEnd="${EPOCHREALTIME/./}"
printf -v tWait %07d "$((tStart + 50000 - tEnd))" # 50000 μs = 0.05 s
sleep "${tWait:: -6}.${tWait: -6}"
stty echo
echo "key was $key"