初歩のシェルスクリプトで遊ぶ[キー入力をEnter無しで受け取りたいがよくわからん]
#!/bin/sh # ==================================================================== # ■ キー入力テスト_ddコマンドでキーを押すとすぐに受け取る_0 # # ▼ 定番のコマンドで動くか? # INPUT_KEY=`dd bs=1 count=1 2>/dev/null` # # ・1バイト受け取るコマンドの定番らしい。これをもとに、1バイトから3バイト受け取りたい。 # ・無限ループの中でキー入力を受け取りたい。 # ・IMEが日本語入力になっているときでも、致命的な問題は起こりにくいようにしないと、使えない。 # # ==================================================================== ctrl_plus_C=`printf '\003'` UP____KEY=`printf '\033[A'` DOWN__KEY=`printf '\033[B'` RIGHT_KEY=`printf '\033[C'` LEFT__KEY=`printf '\033[D'` LOOP_COUNT=0 while true ; do LOOP_COUNT=$(( ${LOOP_COUNT} + 1 )) echo "====== ${LOOP_COUNT} ======" # ddコマンド実行前の下準備 stty_BAK=`stty -g` # sttyの現在の状態を丸ごとバックアップ stty -echo # 入力が端末に表示されないように、エコーバックをOFF stty raw # rawモードに切り替える # (1) 3バイト指定して受け取る ------------------------------------------------- # IMEがOFFで、英数字を入力するなら問題ない # 日本語文字列を一気に入力したりすると、何周もループしてしまう #INPUT_KEY=`dd bs=3 count=1 2>/dev/null ` # (2-1)バイト数を指定せずに1キー受け取る -------------------------------------- # 長い文字列を一気に入力しても何周もループはしない。 # 無指定は不安も残る #INPUT_KEY=`dd count=1 2>/dev/null` # (2-2)先頭3バイトのみ残す ---------------------------------------------------- INPUT_KEY=`dd count=1 2>/dev/null | cut -b 1-3` # ddコマンド実行後の後始末 #stty -raw echo stty "${stty_BAK}" # 入力されたキーを そのまま表示する printf "%s\n" "KEY:${INPUT_KEY}" # 入力されたキーを 16進数で表示する printf "%s" "${INPUT_KEY}" | od -A n -t x1 -v # 入力されたキーを 8進数で表示する printf "%s" "${INPUT_KEY}" | od -A n -t o1 -v # キー入力を受け取って処理を分岐する case "${INPUT_KEY}" in ( ${UP____KEY} ) date ;; ( ${DOWN__KEY} ) cal ;; ( ${RIGHT_KEY} ) pwd ;; ( ${LEFT__KEY} ) ls ;; ( '/' | 'q' | "${ctrl_plus_C}" ) # 終了する exit 0 ;; ( * ) true ;; esac done
readコマンドだと、文字を入れてからEnterが要る。これしないで入力を受け取りたい。
キーボードのカーソルキーで、こう、あれだ。ドラゴンクエストのコマンド選択で、矢印が動くみたいなの。十字キーで動かして、Aボタンで決定するとか。あれをやりたいんだが、よくわからん。
矢印キーは3バイトの入力になってるようなので、これを受け取れればできそうなんだが。
検索して出てくるのはddコマンドで1バイト指定して受け取るものなのだけれど、これだとwhileループが何回も回ってしまう。
いくつか試したところだと、結局は「count=1」だけにして、入力を受け取ってから、長すぎるぶんはcutで削るなりするのが、なんだかんだで簡単、なのかなぁ。いちおう動いちゃいるんだが。
実用するとなると、たとえば、うっかり日本語入力にしていて、ひらがなカタカナ漢字を何文字も一気に流し込んでしまった、ということが起きても、問題にならないようにはしなきゃなんないわけです。