Shell脚本中识别方向键

vim中使用HJKL移动光标,但是有时候人们习惯于使用方向键,这在有一些脚本中实现移动光标选择选项时比较重要。在网络上找到两个方案:

方案一

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#!/bin/bash
akey=(0 0 0)

cESC=`echo -ne "\033"`

while :
do
#这里要注意,这里有-n选项,后跟一个数字,指定输入的字符长度最大值,所以不管key变量的值有多少个字符,都是一个值一个值做循环, 有多少个值就循环多少次
#输入键盘的上下左右键时,都有三个字符(ESC键算一个),所以都是做三次循环,每做一次循环,akey的值都会发生改变
read -s -n 1 key

akey[0]=${akey[1]}
akey[1]=${akey[2]}
akey[2]=${key}

if [[ ${key} == ${cESC} && ${akey[1]} == ${cESC} ]]
then
echo "ESC键"
elif [[ ${akey[0]} == ${cESC} && ${akey[1]} == "[" ]]
then
if [[ ${key} == "A" ]];then echo "上键"
elif [[ ${key} == "B" ]];then echo "向下"
elif [[ ${key} == "D" ]];then echo "向左"
elif [[ ${key} == "C" ]];then echo "向右"
fi
fi
done

方案二

因为上下左右键当中分别含有ABDC,可以利用这一点来做while循环控制输出上下左右键的信号

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#!/bin/bash
key=() #----->自定义一个数组key,为空值
while :
do
read -s -n 1 key #----->这里跟第一种方法类似,就是利用while循环,不过这里有点不一样的地方,就是这个不考虑完整方向键的字符
#的方向键字符组成只要循环中包含A就会输出上键,包含B就会输出下键,以此类推,所以个人觉得这种方法没有第一种方法严谨,第一种方法更适合用来写比较大的脚本

case ${KEY[0]} in
"B")
echo "下键"
;;
"A")
echo "上键"
;;
"D")
echo "左键"
;;
"C")
echo "右键"
;;
*)
continue
esac
done

方案三

通过分析上述两种方案,我们给出第三种方案,即识别[A[B[C[D 也可以区分方向键。代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
NEO_ESC=`echo -ne "\033"`
echo -n "请输入按键"; read -s -n 1 key
if [[ $key == ${NEO_ESC} ]]; then
read -sn 2 SubListDo
case "$SubListDo" in
"[A")
echo "向上"
;;
"[B")
echo "向下"
;;
"[C")
echo "向右"
;;
"[D")
echo "向左"
;;
*)
exit
;;
esac
fi
  • 2024年07月13日, 由于在脚本diary.shzugit.sh中菜单使用了单一的vim方案,在没有实现完美的方向键识别前暂不加入方向键移动光标选择功能。
  • 2024年07月14日, 在上述方案中首先检测是否输入特殊字符,若为特殊字符前导符\033[, 则读取后面两个字符,再对后两个字符分类探测。使用此方法成功在diary.shzugit.sh中引入方向键,home,end,pgup,pgdn控制列表显示,使之成为更加友好的同时兼容vim快捷键的脚本程序。