だから私の取引は次のようになります。 BASHで作業しながら、配列または任意の数の引数を取り、上向きまたは下向き矢印でナビゲートできるインタラクティブメニューを表示する機能関数を構築しました。ユーザーがクリックして入力を終了します。 、目的のメニュー項目を強調表示します(出力は、メニューの実行方法に応じてメニュー項目のインデックスまたは値です):
すべてがうまくいきます。メニューをレンダリングしてから、ユーザー入力でコマンドの目に見えないプロンプトを解析するイベントに応答しますread
(3文字を収集した後に自動的にトリガーされます)。
read -s -n 3 key 2>/dev/null >&2
出力は$key
変数に供給され、次にcase
評価文を介して実行されます。予想される許容入力は次のとおりです。 (
\033[A
上)
\033[A
(下)
""
(入力)これは順番に目的の動作をトリガします。
しかし、私は7つ以上のメニュー項目が導入されているので(私たちはおそらく10個以下に事前設定したでしょう)、ユーザーが好きなメニュー項目の数字をクリックすることをお勧めします。問題がある送信する必要はありません。
私の質問はこれです:
私もうまくいきますが、ユーザーは必須の数字キー(この場合は5)を入力してから、enter
そのステートメントのキーを押す必要があります。これはmyのread
おかげで動作します。ユーザビリティモデルは次のものと反対です。もちろん、数字選択を3回クリックしない限り、グレインは3文字の最小要件をトリガーします(これも直観に反します)。-n 3
read
質問0-9は単一文字\033[A
として-n 3
扱われます(つまり、に変更すると期待-n 1
どおりに機能しますが、矢印キーは失敗し、エスケープ文字のみが収集されます)。
だから私が知りたいのは次のとおりです。を聞く方法はありますか-n 1 {OR} 3 (whichever comes first)
?問題が解決するまで効果がないため、同様の情報を送信したり\n
、\r
類似の情報を送信したりできないようです。つまり、並列プロセスの実行中に入力された値が0から9であることを確認するために、単に離れることができる方法が見つかりませんでした。実証済み)単一文字)。read
-n 3
私はこのアプローチが好きではありません。awk
orを使用できますsed
。expect
(最後の単語はまだ混乱していますが)read
収集の責任があるかどうかは関係ありません。
編集する:
解決策
read -n1 c
case "$c" in
(1) echo One. ;;
(2) echo Two. ;;
($'\033')
read -t.001 -n2 r
case "$r" in
('[A') echo Up. ;;
('[B') echo Down. ;;
esac
esac
ステータス:解決済み
@chorobaが救出に来ます!
ソリューションの説明
私は説明しようとします:
彼の解決策は次のとおりです。巣これら2つのread
ステートメント(順番に試みた)はまさにこれを行い-t.001
(したがって、関数にほぼ即時のタイムアウトを設定します)、繰越読み取りを有効にします。
私の問題は、私が監視したエスケープキーの長さが3文字であることです(したがって、私が設定したフラグ-n3
)。その後、私は特定の事実を受け入れることが重要であることに気づきました。一つ- 文字入力にも有利です。
彼の解決策は、次のようなケースを作成することでした**($'\033')
。
オリジナル
- 「エスケープ文字を読んだ後…」(
**($'\033')
) Create another
read ``(今回は2文字を待つ)、ナノ秒後にタイムアウトを設定し、エスケープされた文字からバックスラッシュを除外します。
この動作はread
明らかに残りの入力を「こぼす」ことです。次 read
探している値がシードされるまでカウントダウンを開始するステートメント。定義された要件フラグが満たされたので、read
2番目の文字セットのケースをテストすることは簡単な問題であることがわかりました。 (そして他のステートメントから来たにもかかわらず、初期化関数はまだ期待された応答を得るので、プログラムは次のようなことをします。最初から見つけようとした結果を得ました。
答え1
読むことができ-n 1
、最初がそうであれば、次の2つを読んで\033
それに応じて反応します。それ以外の場合、番号は直接処理されます。
#!/bin/bash
read -n1 c
case "$c" in
(1) echo One. ;;
(2) echo Two. ;;
($'\033')
read -t.001 -n2 r
case "$r" in
('[A') echo Up. ;;
('[B') echo Down. ;;
esac
esac