shell while 结束循环_Bash技巧:用read命令模拟简易shell,实现一个小游戏(5)

4725d8fc6d26ab63b70dd4ef669066c2.png

本系列文章使用 Linux bash 的 read 命令逐步模拟一个简易的 shell 效果,并实现一个小游戏,从中说明 read 命令的常见用法。

本篇文章主要说明下面的内容:

  • 使用 -n 选项指定读取多少个字符
  • 总结

使用 -n 选项指定读取多少个字符

执行 read 命令读取标准输入,会不停读取输入内容,直到遇到换行符为止。

如果我们预期最多只读取几个字符,可以使用 -n 选项来指定。查看 help read 对 -n 选项说明如下:

-n nchars
return after reading NCHARS characters rather than waiting for a newline, but honor a delimiter if fewer than NCHARS characters are read before the delimiter

即,read -n nchars 指定最多只读取 nchars 个字符,输入 nchars 个字符后,即使还没有遇到换行符,read 也会停止读取输入,返回读取到的内容。

如果在输入 nchar 个字符之前,就遇到换行符,也会停止读取输入。

使用 -n 选项并不表示一定要读取到 nchars 个字符,另外一个 -N 选项表示一定要读取到 nchars 个字符,
这里对 -N 选项不做说明。

下面会在模拟的简易 shell 中实现一个小游戏,增加一点趣味性。
这个小游戏使用 read -n 1 来指定每次只读取一个字符,以便输入字符就立刻停止读取,不需要再按回车。

具体实现代码如下,这也是 tinyshell.sh 脚本最终版的代码:

#!/bin/bash -iif [ $# -ne 0 ]; then    filename="$1"    if test -n "$(tail "$filename" -c 1)"; then        echo >> "$filename"    fielse    filename="/dev/stdin"fifunction game(){    local count=0    local T="T->"    echo -e "NOW, ATTACK! $T"    while read -s -n 1 char; do        case $char in            "h") ((--count)) ;;            "l") ((++count)) ;;            "q") break ;;        esac        for ((i = 0; i < count; ++i)); do            echo -n "    "        done        echo -ne "$T      "    done    echo}while read -ep "tinyshell> " input; do    if [ "$input" == "l" ]; then        ls    elif [ "$input" == "quit" ]; then        break    elif [ "$input" == "root" ]; then        read -s -p "Please input your password: " pwd        # handle with $pwd        echo        echo "Your are root now."    elif [ "$input" == "game" ]; then        game    else        bash -c "${input}"    fi    history -s "${input}"done < "$filename"

主要改动是增加对 game 字符串的处理,输入这个字符串,会执行自定义的 game 函数。
该函数打印 T-> 字符串,像是一把剑(也许吧),然后用 read -s -n 1 char 命令指定每次只读取一个字符,且不回显。

如果输入 l 字符,则把 T-> 字符串的显示位置往右移。
输入 h 字符,则把 T-> 字符串的显示位置往左移。
看起来是一个左右移动的效果。
输入 q 字符,退出该游戏。

具体执行结果如下:

$ ./tinyshell.shtinyshell> gameNOW, ATTACK! T->        T->tinyshell>

由于没有回显输入字符,且始终在同一行显示 T-> 字符串,所以这个打印结果体现不出 T-> 字符串的移动,可以实际执行这个脚本,多次输入 l 、h 字符,就能看到具体效果,最后输入 q 字符退出游戏。

总结

至此,我们已经使用 read 命令来获取用户输入,模拟了一个简易的 shell 效果,可以执行脚本文件,可以通过上下光标键获取到 bash 的历史命令,支持输入密码不回显,还实现了一个小游戏。

总结 read 命令的使用关键点如下:

  • 使用 -p 选项来打印提示字符,模拟 shell 的命令行提示符
  • 使用 -e 选项在交互式 shell 中用 readline 库读取输入,可以避免输入上下光标键显示乱码
  • 使用 -s 选项指定不回显输入内容,可用于输入密码、输入游戏控制按键等情况
  • 使用 -n 1 选项指定只读取一个字符,输入字符立刻结束读取,可以在游戏中快速响应按键,不用按下回车才能响应
  • 使用 “while read” 循环来重定向读取文件,可以逐行读取文件内容,执行相应命令,就像是执行脚本文件

PS:介绍 read 命令的系列文章完结~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值