How to use Bash read with a timeout?
Solution 1:
In bash
, read
has a -t
option where you can specify a timeout. From the manpage:
read [-ers] [-u fd] [-t timeout] [-a aname] [-p prompt] [-n nchars] [-d delim] [name ...]
-t timeout:
cause read to time out and return failure if a complete line of input is not read within timeout seconds. This option has no effect if read is not reading input from the terminal or a pipe.
Transcript below (without hitting ENTER):
$ date ; read -t 10 -p "Hit ENTER or wait ten seconds" ; echo ; date
Tue Feb 28 22:29:15 WAST 2012
Hit ENTER or wait ten seconds
Tue Feb 28 22:29:25 WAST 2012
Another, hitting ENTER after a couple of seconds:
$ date ; read -t 10 -p "Hit ENTER or wait ten seconds" ; date
Tue Feb 28 22:30:17 WAST 2012
Hit ENTER or wait ten seconds
Tue Feb 28 22:30:19 WAST 2012
And another, hitting CTRL-C:
$ date ; read -t 10 -p "Hit ENTER or wait ten seconds" ; echo ; date
Tue Feb 28 22:30:29 WAST 2012
Hit ENTER or wait ten seconds
Solution 2:
The read
builtin has a timeout.
read -t 10
will do it
Solution 3:
Building on the thoughtful answers above, the return value from the read is useful to distinguish between an empty response from the user (for example "Press Enter" for the default action) and a timeout.
read -t 5 -p "Prompt " RESP
if [[ $? -gt 128 ]] ; then
echo -e "\nTimeout"
else
echo "Response = \"$RESP\"" # adding quotes so empty strings are obvious
fi
Another useful tidbit is that the -p "prompt "
is written to stderr (not stdout) so if you're redirecting stderr, the prompt will not be displayed. An example of this would be logging an execution trace to a log file for later analysis. To use read -p Prompt
in this case you can redirect stderr to the user for just the read statement.
set -x
exec 2>logfile
read -t 5 -p "Prompt " RESP 2>/dev/tty