Linux 命令行与 shell 脚本编程大全 18 图形化桌面环境中的脚本编程

本章主要讲解如何使用 Dialog 插件实现图形化的脚本编写,不是重点,所以不会详细介绍

更多精彩

导览

  1. 使用 echo -e 可以在输出内容中穿插制表符、换行符等特殊字符。
  2. 使用 echo -n 可以移除输出字符末尾默认的换行符。
  3. 使用 read -n 1 可以指定只接收用户输入的第一个字符,当检测到一个字符输入后,会直接触发回车操作。
  4. echo read case 命令结合后,可以输出简易的脚本菜单,添加 while [ 1 ] 命令后,可以实现菜单的无限循环。
  5. 使用 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 桌面环境中实现图形脚本效果,不做任何介绍,直接跳过。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342