読む前に標準入力をクリアする


13

次のようなbashスクリプトがあります。

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

ご想像のとおり、 "時間のかかる作業"中にユーザーがランダムキーを押すと、不要な入力も考慮されます。クリア方法 stdin readコマンドを発行する前に(または少なくとも無視して)?


1
私自身、あなたが呪いのようなプログラムを書いていない限り、私はあなたがあなたのプログラムの設計上の欠陥になるためにあなたがしたいことを見つけます。 UNIX / Linuxには、入力をバッファするという非常に便利な機能(「先行入力」)があり、私は一般的にこの機能を利用します。あなたが私のタイプしたものを捨てるところであなたのプログラムに遭遇すると、私はたぶんバグを提出し、それが修正されるまであなたのプログラムを使うのを止めるでしょう。
Arcege

彼らのプログラムが何かをするのに忙しい間、何人かのユーザーは彼らのキーボードでピアノを弾くことの迷惑な習慣を持っています。私はむしろこれらのキーストロークを捨てて、新しく始めることを望みます。しかし、その通りです、「先行入力」は便利ですが、必ずしもそうとは限りません。
rabin

回答:


8

標準入力をクリアする方法はないと思いますが、(bashを使うと)入力を求める前にそこにあるものを読んで破棄することができます。

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

これはstdinを読み、1秒のタイムアウトを持ちます、stdinに10000文字以上がある場合でも失敗します。私はあなたがncharsパラメータをどれくらい大きくできるかわからない。


私は実際にフォーラムでこのハックを見つけました。もっと良い方法が見つかると期待していました。どうやらそうではないです。
rabin

@ラビン:あなたがより良い方法をここに投稿して見つけたら、いくつかのスクリプトでそれを持っています。
Iain

残念ながら、これはすべてのシェルではうまくいきません。 ダッシュ :(
scai

16

Bash 4では、あなたが設定することができます -t (タイムアウト)〜 0。この場合、 read 待機中のデータがあるかどうかを示す終了ステータスを返します。

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

5
read -d '' -t 0.1 -n 10000

ユーザーが誤って複数回入力を押した場合、これは複数行の入力を読み取ります。


5

これは私にとってはうまくいった:

function clean_stdin()
{
    while read -e -t 0.1; do : ; done
}

なぜ -e この場合?
nhed

もうわからない、システム固有の問題を回避するため
pschichtel

4

時間のかかるタスクは、標準入力が閉じられているブロックで囲みます。

{
     # time consuming task
} <&-

read -p "Give me some input: " input

これは質問とは関係がないと思います。
Scott

しかし、そうです!ユーザーはすべての入力を破棄したいです。入力を許可しないことはまさにそれをする - 標準入力が閉じられるので、すべての入力は(システムによって)破棄される。それは彼の問題に対する優雅な解決策です。彼は、システムに廃棄ループを作成する手間をかけずに廃棄を行わせる。
HiTechHiTouch

これはこれまでのところ最も信頼できる選択肢のようです。
Stephen Eilert

3

christophjaegerの答えをもとに、私は付け加えました -s 入力が端末にエコーされないように -n 新しい行を待たないようにするためです。

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

を使う -n これは良い考えですが、以前の2つの回答ですでに述べています。この演習のポイントは、入力されたものをすべて読み、破棄することです。 の前に read 実行された 、私はあなたが何を考えて良いのか分からない -s するつもりです。
Scott

2
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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.