版权声明:原创作品转载必须注明出处 https://blog.csdn.net/u013390088/article/details/82223770
shell 还是很强大很实用的一种工具的
- 我对这种状态机的理解就是一个操作的闭环,即程序在和用户的交互过程中无论用户做出什么选择,程序总是能给出正常的响应——包括错误/警告提示。比如从一个菜单选择开始,进入其中一个选项后选择退出或者下一步都能看到一个响应界面,而不出现程序卡死或异常退出的现象。
- 实现这种状态机主要用到
case
语句来做跳转 - 这里的示例利用表示状态的
STATE
变量对10
取余来实现对跳转过程的划分阶段的功能——0、10-19、20-29分别表示三个阶段 - 简单示例如下
#!/bin/bash
...
# 假设一个实现选择下一步和上一步的函数go,其返回是否进入下一步或是进入上一步
go(){
xxx
}
# STATE表示当前的状态
STATE=10
# LASTSTATE表示上一次完成一个循环后的状态
# 有时两个状态来回切换了,但又没有做修改,利用整个LASTSTATE和STATE作比较可以跳过一些不必要的操作
LASTSTATE=0
while :; do
case $STATE in
0) # 当前脚本以10为返回值表示正常退出,一般调用该脚本的程序对整个返回值10视为正常完成任务的信号
exit 10
;;
10) # 第一个阶段开始
echo '状态$STATE ...'
;;
11) # 第一个阶段的第一步
# 选择是否进入下一步
res=go
if [ $res == 'true' ];then
echo '由于xxx , 直接跳转到STATE=20,**进行阶段的切换**'
STATE=20
continue
fi
echo '状态$STATE ...'
;;
20) # 第二个阶段开始
# 如果上一次还是从这里退出,可以省略重复的操作
if [ $LASTSTATE == $STATE ]; then
continue
fi
echo '状态$STATE ...'
;;
21)# 若干操作
res=go
if [ $res == 'yes' ]; then
# 进行阶段内的步骤的切换
STATE=29
continue
fi
;;
29) # 第二个阶段的阶段末工作
echo '状态$STATE ...'
;;
30) # 第三阶段,整个过程的收尾阶段
echo '状态$STATE ...'
break
;;
*) # 其他的错误退出状态
error '错误退出 ...'
exit 1
;;
esac
LASTSTATE=$STATE
if go; then
# 如果交互的结果是下一步,则状态增1,进入下一步
STATE=$(($STATE + 1))
else
# 如果交互的结果是回到上一步
# 分两种情况
# 一种是在整十的状态(整十的状态表示阶段的开始)下选择回退,则直接退回上一个阶段的开始(上一个整十),即SATTE-10
# 另一种情况是非整十的状态下选择回退,则退回上一步即可,即STATE-1
STATELEVEL=$(($STATE / 10 * 10))
if [ $STATE -eq $STATELEVEL ]; then
STATE=$((STATE -10))
else
STATE=$(($STATE -1))
fi
fi
done
exit 0
- 关于其中的交互函数,在debian软件包开发中,我一般就用debconf了,调用
db_input
等函数实现字符界面的交互。而且注意交互的时候是只有两个选择:上一步或下一步 - 这个示例来自一个叫localechooser的debian软件包,是一种udeb格式的软件包。源码下载,可以直接下载,或是先配上
deb-src
的软件源,然后# apt-get source localechooser
来下载其源码包,其中有一个叫localechooser的bash脚本,以上示例就摘自其中。