接收键盘录入的指令 read, 有几个参数如下,可以按情况组合使用:
-p 在用户等待read输入时输出的提示信息 -t 指定命令等待的时间,超过此时间还未收到用户输入,则终止命令 -n 字符数 # read命令只接收指定的字符数就开始执行,限制用户输入 -s 隐藏输入的数据,适用于密码等机密信息的输入情况
接收键盘常规键比较容易, 但如果是上、下、左、右的方向键可能会要费些周折, 因为它们的输出看上去会很怪,例如
[root@GipagodHost ~]# read ^[[A ^[[B ^[[D ^[[C [root@GipagodHost ~]#
如果过滤掉前边的“怪”字符,通过常规的A、B、C、D也很容判断,但每次按键到底产生了几个字符呢 ? 看上去是4个,实际上是3个,^[ 其实是一个字符,而且 ^[ 这个字符跟键盘录入的字符是不一样的, 它跟ESC键产生的字符是一样的,验证一下:
[root@GipagodHost ~]# read v_key_up #读取上方向键的录入 ^[[A [root@GipagodHost ~]# echo ${#v_key_up} 3 #证明是每次按键是3个字符 [root@GipagodHost ~]# read v_key_esc #读取ESC键的录入 ^[ [root@GipagodHost ~]# echo ${#v_key_esc} 1 #证明^[是一个字符 [root@GipagodHost ~]# if [[ ${v_key_up:0:1} == '^[' ]]; then echo yes; fi #说明^[不是我们键盘录入的普通字符 [root@GipagodHost ~]# if [[ ${v_key_up:0:1} == $v_key_esc ]]; then echo yes; fi #说明^[是和ESC输出一样的字符 yes
过滤掉‘^[’ 和‘[’ 然后就可以根据字母进行按键的判断,但前者过于特殊,不能运行脚本时先让用户按一次ESC键来获取这个字符; 实际上有一个指令可以生成这个特殊字符,如下:
[root@GipagodHost ~]# v_char=`echo -e "\033"` [root@GipagodHost ~]# echo $v_char #该字符常规下不可见 [root@GipagodHost ~]# if [[ ${v_key_up:0:1} == '^[' ]]; then echo yes; fi [root@GipagodHost ~]# if [[ ${v_key_up:0:1} == $v_char ]]; then echo yes; fi yes #可见 echo -e "\033" 确实可以生成这个特殊字符
这样就可以根据用户的按键录入做出不同的操作了。
f_turn_up(){ echo "UP"; } f_turn_down(){ echo "DOWN"; } f_turn_left(){ echo "LEFT"; } f_turn_right(){ echo "RIGHT"; } v_special_char=`echo -e "\033"` while : do read -s -n 1 v_pressed_key # 每次只接受一个字符 v_pressed_key=`echo $v_pressed_key | tr 'a-z' 'A-Z'` # 将字母进行大小写转换,方便后续做判断处理 if [[ $v_pressed_key == 'C' ]] # 通过C键退出循环 then break fi if [[ $v_pressed_key == $v_special_char ]]; then # 首先判断第一个获取的字符是不是^[这个特殊字符, 如果是,那么 read -s -n 2 v_pressed_key # 需要再次获取2个字符,因为每按一次方向键输出3个字符 [[ ${v_pressed_key:1:1} == 'A' ]] && f_turn_up # 通过第二次获取的字符串的第二个字符,很容易就可以判断出用户的按键 [[ ${v_pressed_key:1:1} == 'B' ]] && f_turn_down [[ ${v_pressed_key:1:1} == 'D' ]] && f_turn_left [[ ${v_pressed_key:1:1} == 'C' ]] && f_turn_right fi done
如果使用普通的W、S、A、D进行方向操作,判断起来就更简单了,见以下新增代码部分:
f_turn_up(){ echo "UP"; } f_turn_down(){ echo "DOWN"; } f_turn_left(){ echo "LEFT"; } f_turn_right(){ echo "RIGHT"; } v_special_char=`echo -e "\033"` while : do read -s -n 1 v_pressed_key v_pressed_key=`echo $v_pressed_key | tr 'a-z' 'A-Z'` if [[ $v_pressed_key == 'C' ]] then break fi if [[ $v_pressed_key == $v_special_char ]]; then read -s -n 2 v_pressed_key [[ ${v_pressed_key:1:1} == 'A' ]] && f_turn_up [[ ${v_pressed_key:1:1} == 'B' ]] && f_turn_down [[ ${v_pressed_key:1:1} == 'D' ]] && f_turn_left [[ ${v_pressed_key:1:1} == 'C' ]] && f_turn_right fi #新增代码部分 [[ $v_pressed_key = 'W' ]] && f_turn_up [[ $v_pressed_key = 'S' ]] && f_turn_down [[ $v_pressed_key = 'A' ]] && f_turn_left [[ $v_pressed_key = 'D' ]] && f_turn_right done
效果:
接下来该移动坦克了~