Search code examples
bashtimeoutuser-input

bash read timeout only for the first character entered by the user


I have searched for a simple solution that will read user input with the following features:

  • timeout after 10 seconds, if there is no user input at all
  • the user has infinite time to finish his answer if the first character was typed within the first 10 sec.

I have found a solution to a similar request (timeout after each typed character) on Linux Read - Timeout after x seconds *idle*. Still, this is not exactly the feature, I was looking for, so I have developed a two line solution as follows:

read -N 1 -t 10 -p "What is your name? > " a
[ "$a" != "" ] && read b && echo "Your name is $a$b" || echo "(timeout)"

In case the user waits 10 sec before he enters the first character, the output will be:

What is your name? > (timeout)

If the user types the first character within 10 sec, he has unlimited time to finish this task. The output will look like follows:

What is your name? > Oliver
Your name is Oliver

However, there is following caveat: the first character is not editable, once it was typed, while all other characters can be edited (backspace and re-type).

Do you have any ideas for a resolution of the caveat or do you have another simple solution to the requested behavior?


Solution

  • Enable readline and add $a as the default value for the second read.

    # read one letter, but don't show it
    read -s -N 1 -t 10 -p "What is your name? > " a
    
    if [ -n "$a" ]; then
      # Now supply the first letter and let the user type
      # the rest at their leisure.
      read -ei "$a" b && echo "Your name is $b"
    else
      echo "(timeout)"
    fi
    

    This still displays a second prompt after the first letter is answered, but I don't think there's a better way to handle this; there's no way to "cancel" a timeout for read. The ideal solution would be to use some command other than read, but you would have to write that yourself (probably as a loadable built-in, in C).