#!/bin/bash
#
<.... my script ... (works for about 5 minutes!)>
echo "this is the result: "
[...]
echo "to go on press ENTER"
# here I want to clear stdin
read a
clear # clear the screen
[...]
because the user perhaps unfortunately has pressed some keys and when
read a is promted then a ist filled with the chars of these keys. So
the user doesn't see the result!
How can I clear stdin?
thx
Ekkard
Perhaps: cat - >/dev/null
--
Glenn Jackman
Write a wise saying and your name will live forever. -- Anonymous
> At 2009-05-20 02:04PM, "Ekkard Gerlach" wrote:
>> I want to clear stdin before 'read a':
>>
>> #!/bin/bash
>> #
>> <.... my script ... (works for about 5 minutes!)>
>> echo "this is the result: "
>> [...]
>> echo "to go on press ENTER"
>> # here I want to clear stdin
>> read a
>> clear # clear the screen
>> [...]
>>
>> because the user perhaps unfortunately has pressed some keys and when
>> read a is promted then a ist filled with the chars of these keys. So
>> the user doesn't see the result!
>>
>> How can I clear stdin?
>
> Perhaps: cat - >/dev/null
But that will block if there's nothing in the stdin buffer. I can't think of
a way to do that in shell (which doesn't mean there isn't one of course); a
terrible hack could be using something like
read -t 1 -n <bignumber> dummyvar
before doing the actual read of user input, but it looks like a very poor
solution to me (and of course read must support -t; bash builtin read
does).
> read -t 1 -n <bignumber> dummyvar
>
I'm using bash.
I tried:
#!/bin/bash
#
sleep 5
read -t 1 -n 323423423 dummyvar
read a
echo $a ready
the hack it works! Last input chars are displayed, but that doesn't
matter! The returns during sleep 5 are thrown away.
thx
Ekkard
If your buffer content always end with a newline ($'\n') you can try:
while read;do :;done
If not:
while read -n1;do :;done
>
> If your buffer content always end with a newline ($'\n') you can try:
> while read;do :;done
>
> If not:
> while read -n1;do :;done
sorry, doesn't work in bash. In both examples "read" rests in a endless
loop.
Ekkard
I apologize, obviously "read" will wait forever in stdin (my mistake).
As already said by pk you can use "-t" for read's timeout. I think the
value 1 ("read" limit) is inconveniently high for that purpose, but
new version of bash seems accept lower values:
while read -n1 -t.1 a;do :;done
Bash here is:
$ bash --version|head -n1
GNU bash, version 4.0.24(1)-release (i686-pc-linux-gnu)
This new bash's resource will be very useful to me. :)
> the hack it works! Last input chars are displayed, but that doesn't
> matter! The returns during sleep 5 are thrown away.
Teste the key '-s' of the "read" while cleaning stdin buffer.
> As already said by pk you can use "-t" for read's timeout. I think the
> value 1 ("read" limit) is inconveniently high for that purpose, but
> new version of bash seems accept lower values:
> while read -n1 -t.1 a;do :;done
>
> Bash here is:
> $ bash --version|head -n1
> GNU bash, version 4.0.24(1)-release (i686-pc-linux-gnu)
>
> This new bash's resource will be very useful to me. :)
Ah thanks for the information, I tried with bash 3.2 which accepts only
integer values for -t. Then yes, 0.1 would be better, although that doesn't
make the solution less kludgy :)
Hi pk,
to me your solution seems very good, and in a simple test here, the loop
"while" ( suggested by me) seems not needed.
Then, your solution (using a very low timeout) seems very good to me,
perhaps better than a specif command (one more) in bash only for this purpose.
As reference to others without bash4, behaviour of some versions of bash
that I have here, for the parameter "-t":
PROMPT$ f(){ date +%s.%N;}
PROMPT$ export -f f
PROMPT$ $0 --version|head -n1
GNU bash, version 4.0.24(1)-release (i686-pc-linux-gnu)
PROMPT$ f;read -t1;f
1242991418.271353662
1242991419.276413729
PROMPT$ f;read -t.1;f
1242991423.486857764
1242991423.592517631
PROMPT$ f;read -t.01;f
1242991426.867548100
1242991426.880439021
PROMPT$ f;read -t.001;f
1242991429.878183736
1242991429.884461932
PROMPT$ ls -ldtr /bin/bash*
-rwxr-xr-x 1 root root 679620 2006-05-13 20:55 /bin/bash31*
-rwxr-xr-x 1 root root 674752 2008-01-13 00:59 /bin/bash32*
-rwxr-xr-x 1 root root 676288 2008-05-10 12:28 /bin/bash3239*
lrwxrwxrwx 1 root root 8 2008-05-10 15:32 /bin/bashold -> bash3239*
-rwxr-xr-x 1 root root 674720 2008-11-27 04:55 /bin/bash3248*
-rwxr-xr-x 1 root root 748228 2009-03-13 04:57 /bin/bash4010*
-rwxr-xr-x 1 root root 774180 2009-04-13 21:52 /bin/bash4017*
-r-xr-xr-x 1 root root 6778 2009-05-17 02:07 /bin/bashbug*
-rwxr-xr-x 1 root root 774564 2009-05-17 02:07 /bin/bash4024*
lrwxrwxrwx 1 root root 8 2009-05-17 02:14 /bin/bash -> bash4024*
lrwxrwxrwx 1 root root 8 2009-05-17 02:18 /bin/bash.17 -> bash4017*
PROMPT$ bash3239
PROMPT$ $0 --version|head -n1
GNU bash, version 3.2.39(1)-release (i686-pc-linux-gnu)
PROMPT$ f;read -t.1;f
1242991466.067515682
bash3239: read: .1: invalid timeout specification
1242991466.070565025
PROMPT$ bash4010
PROMPT$ $0 --version|head -n1
GNU bash, version 4.0.10(1)-release (i686-pc-linux-gnu)
PROMPT$ f;read -t.1;f
1242991526.170081626
1242991526.273839251
PROMPT$