1

I have this little bash script with a while loop, that waits for user input, does something and then sleeps for a while:

while true; do
  read input
  echo $input
  sleep 5
done

I don't want it to accept any user input during sleep. The problem is that any input entered in the shell during sleep is processed when the script continues. Is it possible to completely disable user input during the sleep period?

I've seen this: Disabling user input during an infinite loop in bash, but that doesn't really help me here, does it?

Hope someone can help me with this.

2
  • 1
    What do you mean by "accept" user input? Normally, in unix, anything you type while input is not being accepted is echoed immediately, and stored in a buffer so if something reads input later, it'll receive what was typed. This is generally known as "typeahead". Is your script doing something different from this, or do you want it to do something different from this? Commented Mar 20, 2021 at 0:56
  • Thank you for the clarification. I didn't know that. Yes, I want it to do something different, which is to ignore any input received while sleeping and only receive new input after waking up. Commented Mar 20, 2021 at 23:35

2 Answers 2

1

This is what's needed :

#!/usr/bin/env bash
  
hideinput(){
  [ -t 0 ] && stty -echo -icanon time 0 min 0
}
cleanup(){ 
  [ -t 0 ] && stty sane
}
trap cleanup EXIT
trap hideinput CONT

while true; do
  while read -t 0.001 -n 10000 discard; do :; done # Discard anything already inputted.
  cleanup
  read -p "Input something   :  " input
  hideinput
  echo "What you inputted : " $input
  sleep 5
done
Sign up to request clarification or add additional context in comments.

3 Comments

Works like a charm, thank you so much! Seems more like a workaround to me, though. Is what I want to achieve such an unusual thing to do or why isn't there a more straightforward solution? (Don't get me wrong. I'm happy with your solution, I'm just being curious).
Totally agreed. It does seem overkill, but that's the simplest I could get.
Btw: What I actually ended up using was just this one line inspired by the solution by @Philippe: while read -r -t 0.001; do :; done which does exactly what I was trying to do, since hiding user input while sleeping was actually not necessary in my case.
1

I don't know how or if it's possible to disable user input, but if you just want some interactive program not to take inputs made before it has been started, you can use the following command before the program command:

perl -MPOSIX -e 'tcflush 0,0'

This will cause the terminal to ignore the previous user input, but the terminal will still continue to print whatever the user types. If you want to temporarily disable this behavior, you can add the following commands:

stty -echo
...
stty echo

How would your script look like:

while true; do
  perl -MPOSIX -e 'tcflush 0,0'
  read input
  echo $input
  stty -echo
  sleep 5
  stty echo
done

1 Comment

Nice suggestion. It is not quite working, though. This still prints whatever has been typed while sleeping to the console after resuming the script. I guess you would have to use TCIFLUSH as the second argument instead of 0 (see: thegeekdiary.com/…). Something like this should work: perl -MPOSIX -e 'tcflush(STDIN, TCIFLUSH)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.