21

I have the following bash script:

# do some time consuming task here
read -p "Give me some input: " input

Now as you might have guessed, if a user presses some random keys during the "time consuming task", the unwanted input is taken into account as well. How do I clear stdin (or at least ignore it) before I issue the read command?

Duijf
  • 689
rabin
  • 465

7 Answers7

26

In Bash 4, you can set -t (timeout) to 0. In this case, read immediately returns with an exit status indicating whether there's data waiting or not:

# do some time consuming task here
while read -r -t 0; do read -r; done
read -p "Give me some input: " input
19

I don't think there is a way to clear stdin but (with bash) you can read and discard what is there before you ask for the input

#do some time consuming task here
read -t 1 -n 10000 discard 
read -p "Give me some input: " input

This reads stdin and has a timeout of 1 second, it fails though if there are more than 10000 chars in stdin. I don't know how big you can make the nchars parameter.

7
function clear_stdin()
(
    old_tty_settings=`stty -g`
    stty -icanon min 0 time 0

    while read none; do :; done 

    stty "$old_tty_settings"
)

clear_stdin
7
read -d '' -t 0.1 -n 10000

This reads multiple lines of inputs, if the user inadvertently pressed enter multiple times

5

this worked well for me:

function clean_stdin()
{
    while read -e -t 0.1; do : ; done
}
pschichtel
  • 151
  • 1
  • 3
4

Enclose the time consuming task in a block whose stdin is closed:

{
     # time consuming task
} <&-

read -p "Give me some input: " input
wnrph
  • 3,715
  • 1
  • 28
  • 39
0

I long relied on @Илья Антипов's solution: thanks!
Until on a different setup, read blocked (= pause execution). So I ended up using cat.
And added back the double quotes, thanks to the context given by @Kamil Maciorowski.
This code seems to work:

clear_stdin () {
    old_tty_settings="$(stty -g)"
    stty -icanon min 0 time 0
    cat - > /dev/null
    stty "$old_tty_settings"
    unset old_tty_settings
}