[comp.unix.shell] Clearing the input buffer before a read.

news@massey.ac.nz (USENET News System) (11/26/90)

I have an sh script that asks the user a question and reads
the answer into a variable in the usual method.  I want to
be able to flush the input buffer just before the read so
that any slips or double key bounces get ignored, rather than
used as the answer.  I realize this disables type ahead, but
I can live with that.  Anyone know how to do this?

Thanx,
-- 
Ken Spagnolo - Systems Programmer, Postmaster, Usenet Administrator, etc.
   Computer Centre, Massey University, Palmerston North, New Zealand
K.Spagnolo@massey.ac.nz  Phone: +64-63-69099 x8587  New Zealand = GMT+12

tif@doorstop.austin.ibm.com (Paul Chamberlain) (11/27/90)

In article <1990Nov26.001425.15563@massey.ac.nz> K.Spagnolo@massey.ac.nz (Ken Spagnolo) writes:
>I want to
>be able to flush the input buffer just before the read ...

This is pretty nasty but it might do what you want:

	old_modes=`stty -g`		# save old modes
	stty -icanon min '^@' time '^@'	# read whats already there
	read junk			# read all thats waiting
	stty $old_modes			# restore old modes

You may want to make this bullet-proof about interrupts though.

I tried this on AIX Version 2 (RT).

Paul Chamberlain | I do NOT represent IBM.     tif@doorstop, sc30661 at ausvm6
512/838-7008     | ...!cs.utexas.edu!ibmchs!auschs!doorstop.austin.ibm.com!tif

martin@mwtech.UUCP (Martin Weitzel) (11/27/90)

In article <1990Nov26.001425.15563@massey.ac.nz> K.Spagnolo@massey.ac.nz (Ken Spagnolo) writes:
>I have an sh script that asks the user a question and reads
>the answer into a variable in the usual method.  I want to
>be able to flush the input buffer just before the read so
>that any slips or double key bounces get ignored, rather than
>used as the answer.  I realize this disables type ahead, but
>I can live with that.  Anyone know how to do this?

The exact answer depends on your variant of UNIX. Check the ioctl(2)
and/or termio(7) entry of your manual. Usually it describes some method
of how to clear the input buffer. Then write a small C-program (usually
a two-liner) and call that program before executing the read-command
of the shell. On the system I use (ISC UNIX 2.2) such a flush-program
could look like:

#include <termio.h>
main() { (void) ioctl(0, TCFLSH, 0); return 0; }

Alternatively, (and as you have to call a program anyway), you may choose
to let your program read one line of input, and assign this input within
the script by means of the `.....` construct. To save some more typing, you
should include the desired prompt as an argument of your program. Instead
of:
	echo "now> \c"	# send prompt to the user
	flush		# your program to flush input buffer
	read var	# read user's input into var
use
	var=`readline 'now> '`

Here is a very simple version of a readline-program:

#include <termio.h>
#define MAXLINE 80
main(argc, argv)
	int argc; char *argv[];
{
	char buffer[MAXLINE]; int n;
	if (argc > 1) write(1, argv[1], strlen(argv[1]));
	(void) ioctl(0, TCFLSH, 0);
	n = read(0, buffer, MAXLINE);
	if (n <= 0) return 1;
	(void) write(1, buffer, n-1);
	return 0;
}

With more work, (considerably more work, if you want it portable) you
could even add more or less simple editing functions to this program.
(I've done so long time ago, using the termcap database to specify
cursor-keys and control-codes, but the resulting program is too large
to be posted here.)
-- 
Martin Weitzel, email: martin@mwtech.UUCP, voice: 49-(0)6151-6 56 83

D. Allen [CGL]) (11/28/90)

In my limited experience

   stty old new

will flush typeahead in a shell script that has a real tty from which
it is reading.  (BSD 4.3 Unix)
-- 
-IAN! (Ian! D. Allen) idallen@watcgl.uwaterloo.ca idallen@watcgl.waterloo.edu
 [129.97.128.64]  Computer Graphics Lab/University of Waterloo/Ontario/Canada

csx040@cck.cov.ac.uk (Alan Chantler (CS)) (11/30/90)

In article <1990Nov26.001425.15563@massey.ac.nz> K.Spagnolo@massey.ac.nz (Ken Spagnolo) writes:
>I have an sh script that asks the user a question and reads
>the answer into a variable in the usual method.  I want to
>be able to flush the input buffer just before the read so
>that any slips or double key bounces get ignored, rather than
>used as the answer.  I realize this disables type ahead, but
>I can live with that.  Anyone know how to do this?

	OK This is not quite the answer that you seek, but it may help.

	Whenever I want a script to read into a variable (say 'fubar')
	then I use:

		read fubar junk

	This will capture any 'extras' into 'junk', which I ignore.

	Of course it doesn't work unless there is whitespace after
	legitimate input, but it can be extended for any number
	of inputs on a line:

		read x y z junk

	etc.

-- 
AlanC@coventry.ac.uk				| Post: Coventry Polytechnic
JANET: AlanC@uk.ac.coventry			|	Priory Street
INET : AlanC%coventry.ac.uk@nsfnet-relay.ac.uk  |	Coventry, UK
Phone: +44 203 838332				|	CV1 5FB