I have the following bash script:

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

Now every bit 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 practise I clear stdin (or at least ignore it) before I issue the read control?

user avatar

Duijf

681 four silver badges 17 bronze badges

asked April 28, 2011 at 15:30

user avatar

ii

  • Myself, unless y'all are writing a curses-like program, I find what you wish to do to be a pattern flaw in your program. UNIX/Linux has the very useful characteristic of buffering input ("blazon-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 stock-still.

    Apr 29, 2011 at 12:13

  • Some users have annoying habit of playing pianoforte with their keyboard while their program is busy doing something. I would rather throw away those keystrokes and kickoff fresh. But y'all're right, the "blazon-ahead" is useful, but not always.

    Apr 29, 2011 at 15:52

seven Answers seven

I don't retrieve there is a manner to clear stdin merely (with bash) you can read and discard what is there earlier you ask for the input

                  #exercise 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 10000 chars in stdin. I don't know how large yous can make the nchars parameter.

answered Apr 28, 2011 at 16:01

3

  • I actually had constitute this hack on a forum. I was expecting to detect a better way of doing it. Plainly non.

    Apr 28, 2011 at 16:09

  • @rabin: If you practise find a better style postal service back here I have information technology in a few scripts.

    user35787

    Apr 28, 2011 at sixteen:xi

  • Unfortunately this doesn't work with all shells, e.g. nuance :(

    December 7, 2013 at 9:53

In Fustigate 4, yous tin can set -t (timeout) to 0. In this case, read immediately returns with an exit status indicating whether there'due south 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                                  

answered Jul 20, 2013 at xx:48

user avatar

1

  • This only seems to work if the user pressed enter after the keys. If the user has just typed random keys (& no enter press), so the loop exits immediately without clearing the buffered characters.

    Mar 10, 2022 at 6:06

                  function clear_stdin() (     old_tty_settings=`stty -g`     stty -icanon min 0 time 0      while read none; practice :; done       stty "$old_tty_settings" )  clear_stdin                                  

answered Nov 16, 2022 at ix:22

user avatar

4

  • If you leave out give-and-take "function", it would piece of work by dash and by any other POSIX compliant crush.

    Mar xviii, 2022 at 0:57

  • This is one of very few cases where you shouldn't double-quote a variable. Utilize stty $old_tty_settings without quotes. The reason is stty -thou generates output that is unspecified. Implementations of stty are immune to generate output with spaces and later on expect the trounce to dissever it and pass multiple arguments. What is specified is a constraint that the output of stty -g must be safe when unquoted, information technology must not trigger word expansion in a shell.

    Dec 1, 2022 at fifteen:36

  • @KamilMaciorowski I don't get it, is there a downside to the double quotes other than the fact that they aren't necessary?

    Aug 4, 2022 at nine:59

  • @kaan_a When quoted, the control may not work. Information technology totally depends on the implementation of stty. The specification states the tool should empathise its own output (i.e. the output of stty -g) every bit arguments (plural!) and the output shall non require quoting. If quoted, the cord volition be a single argument. The specification does not mention "argument" (singular), stty is not required to understand information technology in this form, it may or may not understand it. Not quoting is the only way that is required to piece of work.

    Aug 4, 2022 at 13:thirty

                read -d '' -t 0.1 -n 10000                              

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

user avatar

answered Dec 4, 2011 at 7:53

user avatar

this worked well for me:

                  function clean_stdin() {     while read -e -t 0.one; exercise : ; done }                                  

answered Jun 17, 2013 at seven:58

user avatar

ii

  • why -e in this case?

    April 18, 2022 at 18:33

  • @nhed non certain anymore, peradventure to circumvent some system specific problem

    Apr xix, 2022 at 23:53

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

                  {      # fourth dimension consuming job } <&-  read -p "Give me some input: " input                                  

answered Dec 4, 2011 at xvi:46

user avatar

four

  • I believe that this has nothing to exercise with the question.

    December 5, 2022 at 20:29

  • But it does! The user wants all input discarded. Non assuasive input does exactly that -- since stdin is airtight, all input is discard (past the system). It's an elegant solution to his trouble. He gets the system to do the discard without the trouble of writing a discard loop.

    May 1, 2022 at 11:26

  • This seems to be the virtually reliable option so far.

    May eighteen, 2022 at xx:46

  • Seems perfect merely does not work for me. I tried bash five.0.0 and 4.4.xix. read will all the same read the get-go line entered during # fourth dimension consuming task. Furthermore, if the script doesn't contain any commands that read stdin after the read then the unread lines are executed on the interactive last after the script terminates. Did anyone successfully exam this?

    February 27, 2022 at 10:56

Building on christophjaeger's answer, I added -s and so that the input is not echoed to the terminal and -north then that it does not wait for a new line.

                  while read -r -t 0; do     read -n 256 -r -s done                                  

answered Feb 24, 2022 at 10:xiv

user avatar

1

  • Using -north is a good idea, but ii previous answers have already mentioned it.  And given that the betoken of this exercise is to read and discard anything that that was typed before the read was executed, I don't understand what good yous call up the -s is going to practise.

    Dec 5, 2022 at twenty:35

Not the reply you're looking for? Scan other questions tagged linux bash beat stdin or inquire your own question.