Clear stdin before reading
Solution 1
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.
Solution 2
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
Solution 3
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
Solution 4
read -d '' -t 0.1 -n 10000
This reads multiple lines of inputs, if the user inadvertently pressed enter multiple times
Solution 5
this worked well for me:
function clean_stdin()
{
while read -e -t 0.1; do : ; done
}
Related videos on Youtube
rabin
Updated on September 18, 2022Comments
-
rabin over 1 year
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?-
Arcege about 13 yearsMyself, unless you are writing a curses-like program, I find what you wish to do to be a design flaw in your program. UNIX/Linux has the very useful feature of buffering input ("type-ahead") and I commonly make use of this functionality. Coming across your program where you throw away what I typed, I would likely submit a bug and stop using your program until it was fixed.
-
rabin about 13 yearsSome users have annoying habit of playing piano with their keyboard while their program is busy doing something. I would rather throw away those keystrokes and start fresh. But you're right, the "type-ahead" is useful, but not always.
-
-
rabin about 13 yearsI actually had found this hack on a forum. I was expecting to find a better way of doing it. Apparently not.
-
user49497 about 13 years@rabin: If you do find a better way post back here I have it in a few scripts.
-
scai over 10 yearsUnfortunately this doesn't work with all shells, e.g. dash :(
-
Scott - Слава Україні over 7 yearsI believe that this has nothing to do with the question.
-
Scott - Слава Україні over 7 yearsUsing
-n
is a good idea, but two previous answers have already mentioned it. And given that the point of this exercise is to read and discard anything that that was typed before theread
was executed, I don't understand what good you think the-s
is going to do. -
nhed about 7 yearswhy
-e
in this case? -
pschichtel about 7 years@nhed not sure anymore, maybe to circumvent some system specific problem
-
HiTechHiTouch about 7 yearsBut it does! The user wants all input discarded. Not allowing input does exactly that -- since stdin is closed, all input is discard (by the system). It's an elegant solution to his problem. He gets the system to do the discard without the trouble of writing a discard loop.
-
Stephen Eilert about 7 yearsThis seems to be the most reliable option so far.
-
Socowi about 5 yearsSeems perfect but does not work for me. I tried bash 5.0.0 and 4.4.19.
read
will still read the first line entered during# time consuming
task. Furthermore, if the script doesn't contain any commands that read stdin after theread
then the unread lines are executed on the interactive terminal after the script terminates. Did anyone successfully test this? -
btalb about 4 yearsThis only seems to work if the user pressed enter after the keys. If the user has just typed random keys (& no enter press), then the loop exits immediately without clearing the buffered characters.
-
jarno about 4 yearsIf you leave out word "function", it would work by
dash
and by any other POSIX compliant shell. -
Kamil Maciorowski over 3 yearsThis is one of very few cases where you shouldn't double-quote a variable. Use
stty $old_tty_settings
without quotes. The reason isstty -g
generates output that is unspecified. Implementations ofstty
are allowed to generate output with spaces and later expect the shell to split it and pass multiple arguments. What is specified is a constraint that the output ofstty -g
must be safe when unquoted, it must not trigger word expansion in a shell. -
kaan_a almost 3 years@KamilMaciorowski I don't get it, is there a downside to the double quotes other than the fact that they aren't necessary?
-
Kamil Maciorowski almost 3 years@kaan_a When quoted, the command may not work. It totally depends on the implementation of
stty
. The specification states the tool should understand its own output (i.e. the output ofstty -g
) as arguments (plural!) and the output shall not require quoting. If quoted, the string will be a single argument. The specification does not mention "argument" (singular),stty
is not required to understand it in this form, it may or may not understand it. Not quoting is the only way that is required to work. -
Admin almost 2 years
read -n 256 -r -s
waits for newline unless you give 256 characters. On the other hand,read -r -t 0
returns 1 unless you press enter.