Solution to the "read -t 0" problem

In my bash Freecell, I use “read -t 0” to implement a “spinner” – a decoration that runs while the program waits for input. The “-t 0” (timeout zero) option is supposed to check for input without actually reading anything. As soon as the “read -t 0” succeeds, I stop spinning and use a normal read to read the next user command.

There is one problem: The regular read does not echo the user reply properly. The cursor keeps jumping back to the spinner! I tried using “tput cup” to set the cursor position explicitly, but in that case, the reply writes over itself. I cannot explain why this is happening. Why is the echo function of the second read affected by the timeout option of the first read?!

I did find a circumvention, however. I use “tput sc” to save the cursor before the call to the spinner function and a “tput rc” after the call. The cursor used by the read is saved, and then restored and the subsequent characters of the reply are placed at the restored position.

Update: I’ve made additional changes to the script and now the problem has recurred, even with sc/rc. However, I found a second circumvention that appears to be solid: I add a second “read -t 0” statement, just before the operative “read”.

Here’s what seems to be happening.

  1. The first read with -t 0 accumulates my keystrokes without actually reading them into a variable or REPLY
  2. The operative read dumps these keystrokes into the reply field on the screen
  3. It then resets the cursor position to the beginning of the field, so that my keystrokes are overwritten by the rest of my reply

When I put a second read -t 0 just before the operative read, with no intervening cursor operations, the operative read honors the cursor position that results from echoing my initial keystrokes