本章主要讲解如何使用 Dialog 插件实现图形化的脚本编写,不是重点,所以不会详细介绍
更多精彩
- 更多技术博客,请移步 IT人才终生实训与职业进阶平台 - 实训在线
导览
- 使用
echo -e
可以在输出内容中穿插制表符、换行符等特殊字符。 - 使用
echo -n
可以移除输出字符末尾默认的换行符。 - 使用
read -n 1
可以指定只接收用户输入的第一个字符,当检测到一个字符输入后,会直接触发回车操作。 - 将
echo read case
命令结合后,可以输出简易的脚本菜单,添加while [ 1 ]
命令后,可以实现菜单的无限循环。 - 使用
dialog
组件可以为 Shell 脚本提供丰富的窗口效果,让 Shell 脚本更生动。
18.1 创建文本菜单
在 Shell 脚本中,最适合用来创建菜单的是 case
命令。
18.1.1 创建菜单布局
为了确保进去脚本菜单时,终端界面能只显示脚本菜单,可以在菜单命令前添加 clear
命令,可以立即清除终端界面的文本。
在默认情况下,echo
命令只能输出文本字符,如果想在文本字符中添加例如 制表符 、换行符 等特殊字符,只需要使用 echo -e
即可,代码如下:
上述场景中,第一次使用
echo
命令直接输入字符,结果制表符被当作普通字符直接输出勒,第二次使用 echo -e
输出相同的字符,制表符被识别后成功输出。
在默认情况下,echo
命令输出文本字符后会自动换行,为了让输入的字符紧跟在输出文本之后,可是使用 echo -n
来过滤掉末尾的换行符,代码如下:
首先介绍一下
read -n 1
的作用,该命令表示只接收用户输入的第一个字符,当用户输入第一个字符后,就自动触发回车操作,不需要用户再次手动回车 。
上述场景中,目的是在输出内容后接收用户的输入,但直接使用
echo
输出文本后,会自动换行,后续输入的文本出现在下一行,这很显然不够美观。
接下来使用
echo -n
输出文本,可以看到,末尾的换行符被自动过滤掉,后续输入的文本紧随其后,这种效果就符合我们的预期。
但由于输入的脚本默认不会自动换行,所以一般还会在输入的脚本后追加一个空的
echo
命令由于换行。
18.1.2 创建菜单函数
为了让代码更美观,在编写菜单时,通常会将相关代码单独提炼成一个函数,代码如下:
上述代码的运行结果如下:
18.1.3 添加菜单逻辑
当接收到菜单的输入选项后,使用 case
命令对选项进行判断,并进入对应分支即可,代码如下:
上述代码中,当选择 0 时,会直接触发
break
是因为后续会将菜单使用 while
命令实现菜单的无限循环,所以当用户选择退出脚本时,直接通过 break
来触发循环结束。
需要注意的是 ,在 Shell 脚本中,函数的创建需要放在调用之前,否则会出现找不到函数的异常。
上述代码的运行结果如下:
18.1.4 整合 shell 脚本菜单
优化后的脚本如下,将菜单的选择操作抽离成单独的函数,然后使用 while [ 1 ]
命令包裹函数,即可实现菜单的无限循环。
需要注意的是 ,在以下代码中,当菜单初始化后,还使用 echo + read
的方式继续接收用户输入,这样做的目的是为了暂停循环,防止当某个菜单分支执行后,脚本的输出结果直接被 clear
命令清空。通常情况下,用户都需要确认一下脚本的输出结果,在手动触发下次菜单循环。
以上代码的部分运行结果如下图:
18.1.5 使用 select 命令
为了简化菜单的构建步骤,Linux 提供了 select
命令用于快速创建菜单。使用 select
命令只需要一条命令即可创建菜单,然后获取输入的答案并自动处理。完整语法如下:
select variable in list
do
commands
done
上述代码中,list
参数用于存放菜单项,不同的菜单项使用空格分隔即可。每个菜单项会自动标记编号。
使用 select
命令对之前的菜单脚本进行优化后的代码如下:
在上述代码中,可以看到,通过使用
select
命令,在实现相同功能的前提下,脚本的代码量减少了 15 行,首先是不需要再使用 echo
命令对菜单进行排版和输出,其次也不需要使用 while [ 1 ]
命令来对菜单进行无限循环。
需要在注意的是 ,
select
命令中变量 option
返回的值不是菜单的编号,而是菜单的具体内容,所以在 case
命令中进行判断时,需要确保每个菜单分支的内容和 select
命令中保持一致。
上述代码的运行结果如下:
18.2 使用 dialog 制作脚本窗口
使用 dialog 可以在终端界面中实现类似于窗口的效果。实现原理是使用 ANSI 转义控制字符在本文环境中创建标准的窗口对话框。
使用 yum info dialog
可以在系统中查看到以下信息:
使用
yum install dialog
会默认安装 x86_64 版本。
18.2.1 dialog 包
使用 dialog
命令可以通过添加命令行参数来决定生成哪种窗口组件。支持的组件有很多,这里不做一一介绍。具体语法如下:
dialog --widget parameters
每个组件都提供以下两种形式的输出:
* STDEER
* 退出状态码
对于存在按钮的组件,选择 Yes 或 Ok 按钮,会返回退出状态码 0 ,选择 Cancel 或 No 按钮,会返回退出状态码 1 。
如果组件返回的是较为复杂的数据,则通过 STDEER 将内容输出,可以直接将输出内容重定向到具体文件中。
18.2.1.1 msgbox 组件
msgbox 组件会在窗口中央显示一条简单的消息,直接用户触发 Ok 按钮后才消失,语法如下:
dialog --msgbox text height width
上述语法中,text
用于指定窗口的主体内容,height
指定窗口高度,width
指定窗口宽度。
如果想为窗口自定义标题,添加 --title title
指令即可,完整语法如下:
dialog --title title --msgbox text height width
上述语法的实际应用如下:
dialog --title "神奇的 msgbox 组件" --mgsbox "小朋友你是否有很多问号?" 10 20
上述代码的实现效果如下:
这样看上去还是蛮神奇的,直接按键盘上的回车键就可以退出该组件,效果如下:
通过上面这个图片基本就可以了解到 dialog 渲染的方式就是终端的当前界面,所以当不断按回车键换行时,界面也就慢慢的被推移上去了。
18.2.1.2 yesno 组件
yesno 组件是对 msgbox 组件的扩展,允许用户对窗口中显示的问题选择 yes 或 no ,使用效果如下:
在上图的窗口中,可以使用方向键在两个按钮中进行切换,之后按回车就可以选择指定按钮。当选择按钮后,使用
echo $?
命令就可以捕获到按钮的选择结果,Yes 返回 0 ,No 返回 1 。
18.2.1.3 inputbox 组件
inputbox 组件为用户提供一个简单的文本框区域用于输入文本字符串,输入的字符串内容会被 dialog 发送给 STDEER ,必须将 STDEER 重定向到指定文件,才能获得输出内容,使用效果如下:
上图中,使用
2>age-result.txt
就是将组件的输出内容重定向到指定文件,因为 STDEER 的数字编号是 2 。查看文件中的输出结果时会发现,输出内容默认不带换行符,这是为了方便在 Shell 脚本中直接将输出的值赋予变量。
18.2.1.4 textbox 组件
textbox 组件可用于在窗口中显示大量信息,该窗口会生成一个带滚动条的界面,用于显示指定文件中的所有文本,使用效果如下:
在窗口退出之前,可以使用上下箭头对窗口中的内容进行滚动查看。
18.2.1.5 menu 组件
menu 组件可以在窗口中创建指定菜单,效果如下:
代码中的 15 表示高度,30 表示宽度,10 表示一次显示的菜单项总数 ,后续内容则是 序号 + 菜单项 的列表。所选择的菜单项输出同样需要被重定向到指定文件。
18.2.1.6 fselect 组件
fselect 组件可以创建一个浏览指定目录的文件列表,效果如下:
在该窗口中,直接输入字符,会将内容输入到最下方的输入框中,同时右侧的列表会对输入内容进行匹配,在匹配的文件上按下空格,就可以选中该文件,之后按回车,会退出窗口,同时将选中的文件名称发送到重定向的文件中。
18.2.2 dialog 选项
除了标准组件,还可以在 dialog
命令中添加不同的选项来定制窗口显示效果,--title title
指定窗口的标题就是其中之一。其他选项不做过多介绍。
18.2.3 在脚本中使用 dialog 命令
接下来我们尝试使用 dialog
命令来实现一开始的循环菜单,代码如下:
在上述代码中,构建步骤如下:
1. 创建了临时文件用于存放菜单的选择项。
2. 在初始化菜单的函数中,创建了菜单,并将选择项重定向到临时文件中。
3. 使用
if
命令判断用户是否在菜单窗口选择了退出按钮。
4. 使用
cat
命令查看临时文件中用户选择的菜单项,并赋值给 option 变量
5. 使用
case
命令判断 option 变量的值。
6. 使用
while [ 1 ]
命令实现菜单的无限循环。
7. 最后删除临时文件。
代码运行后的效果如下:
18.3 使用图形
本节介绍的内容是如何在 KDE 和 GNOME 桌面环境中实现图形脚本效果,不做任何介绍,直接跳过。