こんにちは、山田ハヤオです。
ターミナルというのは非常に奥が深く、遊んでると結構楽しいものです。
シェルスクリプトで矢印キーを用いたメニューを実装したいと思い、手始めに矢印キーの検知を実装してみました。
日本語情報はほぼ無く、RadditやStack Overflowを参考にしました。
最終的に、仕組みをほぼ理解していなくても使える汎用できなものができました。
この記事のコードを使って最終的にできたのが、これらです。
ソースコード
Bash 5.xで動作することを確認しています。POSIXは無視してます。
capture_special_keys(){
local SELECTION rest
IFS= read -r -n1 -s SELECTION
if [[ $SELECTION == $'\x1b' ]]; then
read -r -n2 -s rest
SELECTION+="$rest"
else
case "$SELECTION" in
"")
echo "Enter"
;;
$'\x7f')
echo "Backspace"
;;
$'\x20')
echo "Space"
;;
*)
read -i "$SELECTION" -e -r rest
echo "$rest"
;;
esac
return 0
fi
case $SELECTION in
# backspace
$'\x1b\x5b\x41') #up arrow
echo "Up"
;;
$'\x1b\x5b\x42') #down arrow
echo "Down"
;;
$'\x1b\x5b\x43') #right arrow
echo "Right"
;;
$'\x1b\x5b\x44') #left arrow
echo "Left"
;;
esac
}
使い方
上の関数をスクリプトに貼り付けてから、こんな感じで使います。
entered_key="$(capture_special_keys)"
そうすると入力待機に入り、入力されたキーの名前がentered_keyに代入されます。
スペースキーなら「Space」、バックスペースキーなら「BackSpace」という感じです。
物理的なキー | 返される値 |
エンター | Enter |
スペースキー | Space |
バックスペースキー | BackSpace |
上矢印(↑) | Up |
下矢印(↓) | Down |
右矢印(→) | Right |
左矢印(←) | Left |
普通のキーが入力された場合
普通の数字や英字が入力された場合、通常のreadコマンドと同じふるまいをしようとします。
この処理を無効化して、例外処理などを実行させたい場合は、19~20行目あたりのcase文内の*)
内を書き換えてください。
仕組み
readコマンドのオプションの意味
この関数はBashの機能を色々フル活用しているのでその紹介です。
オプション | 意味 |
-r | バックスラッシュをエスケープ文字として解釈しない |
-s | 入力された文字をターミナルに表示しない |
-n<数字> | 指定された文字数入力された時点でreadコマンドを終了 |
-e | READLINEライブラリを用いる |
-i <Text> | デフォルトで入力されている文字を設定(-eと共に使用する) |
詳しくはBashのmanページの組み込みコマンドのセクションを参照するといいです。
関数の説明
入力されたキーは特殊なコードとして標準入力に与えられるそうなので、readコマンドでそれらを拾います。
\xb1
みたいなこれはどこでどうやって定義されているのかはよくわかりません。
loadkeysとかで設定するキーマップにでもあるんでしょうか?詳しい人いたらどなたか教えてほしいです。
入力されたのが特殊なコードでない場合、通常のreadコマンドと似た感じで動くようにします。
1つ目のread -n1で1文字だけ拾ってしまっているので、caseで処理後の2回目のread時に-iを利用してデフォルト値に設定することで、如何にも最初から入力されていたかのように振る舞います。
使用例
上の動画のメニューのソースコードを貼っておきます。
いくつかファイルがありますが、select.shが一番しっかりしてます。
ライセンス
このページの自分が書いたコードは全てWTFPLで再ライセンスします。
以下ライセンス原文です。
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE Version 2, December 2004 Copyright (C) 2004 Sam Hocevar <sam@hocevar.net> Everyone is permitted to copy and distribute verbatim or modified copies of this license document, and changing it is allowed as long as the name is changed. DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. You just DO WHAT THE FUCK YOU WANT TO.
参考サイト
参考にしたサイトを貼っておきます。
コメント