微信公众号:进击的大杂烩
欢迎关注我,一起学习,一起进步!
脚本中的交互式菜单系统信息菜单相关知识点selectcase
Unix/Linux 上常见的 Shell 脚本解释器有bash、sh、csh、ksh等,bash是Linux标准默认的shell,本文所说的 Shell 就是指 bash。每篇文章都是通过一个简单的脚本来讲解 Shell 和 Linux 系统的一些知识。
脚本中的交互式菜单
写脚本的时候会碰到创建交互式菜单的情况,比如用户选择安装软件的版本或者选择安装各种组件,总之在 shell 脚本中创建菜单是很常见的,并且也是非常有用的。shell 内置的 select 命令让创建交互式菜单变的非常容易。
系统信息菜单
将如下代码保存为 shell 脚本,并运行。
#!/bin/bash
#
# zhuzhu 2019-05-28
#
# Env OS: CentOS Linux release 7.1.1503 (Core), BashShell: GNU bash, version 4.2.46(1)-release (x86_64-redhat-linux-gnu)
#
# git: https://github.com/zshmmm/shell.git
#
# useful_menu.sh
#
clear
echo -e "\n\t\t系统信息菜单\n"
PS3="选择一个选项, 然后按Enter键: "
MENU="OS Host Filesystems Date Users Quit"
select i in $MENU
do
case $REPLY in
1)
echo
echo -n "$i: "; uname
;;
2)
echo
echo -n "$i: "; hostname
;;
3)
echo
echo -n "$i: "; df -h
;;
4)
echo
echo -n "$i: "; date
;;
5)
echo
echo -n "$i: "; who
;;
6)
break
;;
*)
echo "请选择正确的选项"
;;
esac
echo
read -p "按回车继续..."
clear
echo -e "\n\t\t系统信息菜单\n"
done
clear
运行之后会出现一个菜单选择界面,输入相应的菜单编号后打印相应的信息。
比如选择 2 之后会打印当前服务器的主机名。
相关知识点
本文主要讲解 select 的用法
select
select 是建立菜单的一种工具,语法结构为:
PS3=定义select提示符
select variable [in list]
do
do something
done
可见 select 的语法结构非常像一个循环结构,可以根据相应的选择配合 case 执行相应的分支代码块。
如果忽略了 [in list] 则 select 命令将会使用传递到脚本的命令行参数($@
), 或者是函数参数(当select是在函数中时)。
脚本中用到的 PS3
,在 shell 用有 PS1, PS2, PS3, PS4 四种提示符变量,其中 PS1 大家应该是比较熟悉的,用来定义默认的命令行提示符。可以通过 echo $PSx 来查看相应提示符的当前配置。这里不做过多讲解,可以自行百度。其中 PS3 就是用来设置 select 提示符的,在上面脚本中将其设置为:选择一个选项, 然后按Enter键:,运行脚本时应该已经看到了效果。如果没有设置的话默认的提示符为:#?。
脚本中 select i in $MENU
,select 会将 OS Host Filesystems Date Users Quit 这个列表编号并生成菜单选项。当输入编号时,会将对于编号的菜单字符串赋值给 $i
。
脚本中 REPLY 变量为选择菜单的编号。
注意脚本中的 break,select 不会主动退出,如果不设置退出点,select 将不停的循环进行选择。
case
case 是 shell 内建的一种分支选择结构(类似于 if elif else fi,也具备一些 if 不具备的功能),也是非常的强大。
语法结构为:
case WORD in
pattern1)
commands1
;;
pattern2)
commands2
;;
esac
case 比较的是 pattern(通配符支持一些基本正则表达式),当匹配到之后执行相应的 commands 。而后的 ;;
表示结束 case 匹配,不再继续向下匹配。还有其他形式 ;&
;;&
。下面通过2个例子来看一下效果。更详细用法可以查看相关文档。
#!/bin/bash
#
# 将多个输入选项执行同一个动作
#
# 例子中可以用 y|Y 来实现相同的效果,这里为了只是为了演示 ;&
#
read -p "你喜欢 LOL 么:(y/n):" ans
case $ans in
y)
;&
Y) echo "是的非常喜欢"
;;
n)
;&
N) echo "不, 我更喜欢英雄联盟"
;;
esac
#!/bin/bash
#
# 根据输入匹配的精确度输出不同的结果
#
read -p "请输入一个区号:" num
case $num in
*)
echo -n "中国"
;;&
03*)
echo -n "河北省"
;;&
??10)
echo "邯郸市"
;;
??11)
echo "石家庄"
;;
??17)
echo "沧州市"
;;
07*)
echo -n "广东省"
;;&
??51)
echo "韶关市"
;;
??54)
echo "汕头市"
;;
??56)
echo "珠海市"
;;
*)
echo
;;
esac
脚本中 case 是根据 $REPLY 的值选择相应的分支结构代码执行。*)
匹配所有,用于匹配前面没有任何一个通配符匹配的情况。