禅道博客

分享专业技术知识,文章内容干货满满

《Linux命令行与shell脚本编程大全》第十八章:制作窗口

2022-12-05 09:48:29
胡爱荣
原创 151
摘要:本文详细介绍了《Linux命令行与shell脚本编程大全》中,关于“如何制作窗口”的内容。

一、 制作窗口

dialog包最早是由Savio Lam创建的一个小巧的工具,现在由Thomas E. Dickey维护。该包能 够用ANSI转义控制字符在文本环境中创建标准的窗口对话框。你可以轻而易举地将这些对话框 融入自己的shell脚本中,借此与用户进行交互。

可以使用下面的命令来进行安装:sudo apt-get install dialog

1.1 dialog包

dialog命令使用命令行参数来决定生成哪种窗口部件(widget)。部件是dialog包中窗口元素类型的术语。dialog包现在支持下面的部件类型。
  • calendar 提供选择日期的日历
  • checklist 显示多个选项(其中每个选项都能打开或关闭)
  • form 构建一个带有标签以及文本字段(可以填写内容)的表单
  • fselect 提供一个文件选择窗口来浏览选择文件
  • gauge 显示完成的百分比进度条
  • infobox 显示一条消息,但不用等待回应
  • inputbox 提供一个输入文本用的文本表单
  • inputmenu 提供一个可编辑的菜单
  • menu 显示可选择的一系列选项
  • msgbox 显示一条消息,并要求用户选择OK按钮
  • pause 显示一个进度条来显示暂定期间的状态
  • passwordbox 显示一个文本框,但会隐藏输入的文本
  • passwordform 显示一个带标签和隐藏文本字段的表单
  • radiolist 提供一组菜单选项,但只能选择其中一个
  • tailbox 用tail命令在滚动窗口中显示文件的内容
  • tailboxbg 跟tailbox一样,但是在后台模式中运行
  • textbox 在滚动窗口中显示文件的内容
  • timebox 提供一个选择小时、分钟和秒数的窗口
  • yesno 提供一条带有Yes和No按钮的简单消息
在命令行上指定某个特定的部件,需使用双破折线格式

dialog --widget parameters

其中widget是部件名,parameters定义了部件窗口的大小以及部件需要的文本。

每个dialog部件都提供了两种形式的输出
  1. 使用STDERR;
  2. 使用退出状态码。
可以通过dialog命令的退出状态码来确定用户选择的按钮。如果选择了Yes或OK按钮, dialog命令会返回退出状态码0。如果选择了Cancel或No按钮,dialog命令会返回退出状态码1。 可以用标准的$?变量来确定dialog部件中具体选择了哪个按钮。

如果部件返回了数据,比如菜单选择,那么dialog命令会将数据发送到STDERR。可以用标 准的bash shell方法来将STDERR输出重定向到另一个文件或文件描述符中。

dialog --inputbox "Enter your age:" 10 20 2>age.txt

1.1.1 msgbox部件

msgbox部件是对话框中最常见的类型。它会在窗口中显示一条简单的消息,直到用户单击 OK按钮后才消失。使用msgbox部件时要用下面的格式。

dialog --msgbox text height width

text参数是你想在窗口中显示的字符串。dialog命令会根据由height和width参数创建的 窗口的大小来自动换行。如果想在窗口顶部放一个标题,也可以用--title参数,后接作为标题 的文本。

msgbox部件示例:dialog --title Testing --msgbox "这是测试msgbox部件" 10 20

1.1.2 yesno部件

yesno部件进一步扩展了msgbox部件的功能,允许用户对窗口中显示的问题选择yes或no。 它会在窗口底部生成两个按钮:一个是Yes,一个是No。用户可以用鼠标、制表符键或者键盘方向键来切换按钮。要选择按钮的话,用户可以按下空格键或者回车键。

dialog --title "Please answer" --yesno "选择yes or no?" 10 20
dialog命令的退出状态码会根据用户选择的按钮来设置。如果用户选择了No按钮,退出状态码是1;如果选择了Yes按钮,退出状态码就是0。

1.1.3 inputbox部件

inputbox部件为用户提供了一个简单的文本框区域来输入文本字符串。dialog命令会将文 本字符串的值发给STDERR。你必须重定向STDERR来获取用户输入。

inputbox提供了两个按钮:OK和Cancel。如果选择了OK按钮,命令的退出状态码就是0;反之,退出状态码就会是1。

dialog --inputbox "Enter your addr:" 10 20 2>addr.txt

1.1.4 textbox部件

textbox部件可以在窗口中显示大量的信息。它会生成一个滚动窗口来显示由参数所指定的文件中的文本。

dialog --textbox /etc/passwd 15 45
可以用方向键来左右或上下滚动显示文件的内容。窗口底部的行会显示当前查看的文本处于 文件中的哪个位置(百分比)。文本框只包含一个用来选择退出部件的Exit按钮。

1.1.5 menu部件

menu部件允许创建我们之前所制作的文本菜单的窗口版本。只要为每个选项提供一个选择标号和文本就行了。

dialog --menu "Sys Admin Menu" 12 30 10 1 "Display disk space" 2 "Display users" 3 "Display memory usage" 4 "Exit" 2> test.txt
第一个参数定义了菜单的标题,之后的两个参数定义了菜单窗口的高和宽,而第四个参数则 定义了在窗口中一次显示的菜单项总数。如果有更多的选项,可以用方向键来滚动显示它们。 在这些参数后面,必须添加菜单项对。第一个元素是用来选择菜单项的标号。每个标号对每个菜单项都应该是唯一的,可以通过在键盘上按下对应的键来选择。第二个元素是菜单中使用的文本。

1.1.6 fselect部件

fselect部件在处理文件名时非常方便,不用强制用户键入文件名,就可以用fselect部件来浏览文件的位置并选择文件。

dialog --title "Select a file" --fselect $HOME/ 10 50 2>file.txt

fselect选项后的第一个参数是窗口中使用的起始目录位置。fselect部件窗口由左侧的目 录列表、右侧的文件列表(显示了选定目录下的所有文件)和含有当前选定的文件或目录的简单 文本框组成。可以手动在文本框键入文件名,或者用目录和文件列表来选定(使用空格键选择文 件,将其加入文本框中)。

1.2 dialog选项

dialog命令选项

--add-widget 继续下个对话框,直到按下Esc或Cancel按钮
--aspect ratio 指定窗口宽度和高度的宽高比
--backtitle title 指定显示在屏幕顶部背景上的标题
--begin x y 指定窗口左上角的起始位置
--cancel-label label 指定Cancel按钮的替代标签
--clear 用默认的对话背景色来清空屏幕内容
--colors 在对话文本中嵌入ANSI色彩编码
--cr-wrap 在对话文本中允许使用换行符并强制换行
--create-rc file 将示例配置文件的内容复制到指定的file文件中
--defaultno 将yes/no对话框的默认答案设为No
--default-item string 设定复选列表、表单或菜单对话中的默认项
--exit-label label 指定Exit按钮的替代标签
--extra-button 在OK按钮和Cancel按钮之间显示一个额外按钮
--extra-label label 指定额外按钮的替代标签
--help 显示dialog命令的帮助信息
--help-button 在OK按钮和Cancel按钮后显示一个Help按钮
--help-label label 指定Help按钮的替代标签
--help-status 当选定Help按钮后,在帮助信息后写入多选列表、单选列表或表单信息
--ignore 忽略dialog不能识别的选项
--input-fd fd 指定STDIN之外的另一个文件描述符
--insecure 在password部件中键入内容时显示星号
--item-help 为多选列表、单选列表或菜单中的每个标号在屏幕的底部添加一个帮助栏
--keep-window 不要清除屏幕上显示过的部件
--max-input size 指定输入的最大字符串长度。默认为2048
--nocancel 隐藏Cancel按钮
--no-collapse 不要将对话文本中的制表符转换成空格
--no-kill 将tailboxbg对话放到后台,并禁止该进程的SIGHUP信号
--no-label label 为No按钮指定替代标签
--no-shadow 不要显示对话窗口的阴影效果
--ok-label label 指定OK按钮的替代标签
--output-fd fd 指定除STDERR之外的另一个输出文件描述符
--print-maxsize 将对话窗口的最大尺寸打印到输出中
--print-size 将每个对话窗口的大小打印到输出中
--print-version 将dialog的版本号打印到输出中
--separate-output 一次一行地输出checklist部件的结果,不使用引号
--separator string 指定用于分隔部件输出的字符串
--separate-widget string 指定用于分隔部件输出的字符串
--shadow 在每个窗口的右下角绘制阴影
--single-quoted 需要时对多选列表的输出采用单引号
--sleep sec 在处理完对话窗口之后延迟指定的秒数
--stderr 将输出发送到STDERR(默认行为)
--stdout 将输出发送到STDOUT
--tab-correct 将制表符转换成空格
--tab-len n 指定一个制表符占用的空格数(默认为8)
--timeout sec 指定无用户输入时,sec秒后退出并返回错误代码 --title title 指定对话窗口的标题
--trim 从对话文本中删除前导空格和换行符
--visit-items 修改对话窗口中制表符的停留位置,使其包括选项列表
--yes-label label 为Yes按钮指定替代标签

1.3 在脚本中使用dialog命令

在脚本中使用dialog命令要注意以下两点:
  • 如果有Cancel或No按钮,检查dialog命令的退出状态码;
  • 重定向STDERR来获得输出值。
示例:使用dialog部件来生成我们之前所创建的系统管理菜单。
这段脚本用while循环和一个真值常量创建了个无限循环来显示菜单对话。这意味着,执行 完每个函数之后,脚本都会返回继续显示菜单。 由于menu对话包含了一个Cancel按钮,脚本会检查dialog命令的退出状态码,以防用户按下Cancel按钮退出。因为它是在while循环中,所以退出该菜单就跟用break命令跳出while循环一样简单。 脚本用mktemp命令创建两个临时文件来保存dialog命令的数据。第一个临时文件$temp用来保存df和meminfo命令的输出,这样就能在textbox对话中显示它们了。第二个临时文件$temp2用来保存在主菜单对话中选定的值。

二、使用图形

KDE和GNOME桌面环境都扩展了dialog命令的思路,包含了可以在各自环境下生成X Window图形化部件的命令。

2.1 KDE环境

KDE图形化环境默认包含kdialog包。kdialog包使用kdialog命令在KDE桌面上生成类似于 dialog式部件的标准窗口。生成的窗口能跟其他KDE应用窗口很好地融合,不会造成不协调的感觉。

2.1.1 kdialog部件

kdialog命令的格式
kdialog display-options window-options arguments

window-options选项允许指定使用哪种类型的窗口部件,可用的选项如下

--checklist title [tag item status]   带有状态的多选列表菜单,可以表明选项是否被选定
--error text   错误消息框
--inputbox text [init]   输入文本框。可以用init值来指定默认值
--menu title [tag item]   带有标题的菜单选择框,以及用tag标识的选项列表
--msgbox text   显示指定文本的简单消息框
--password text   隐藏用户输入的密码输入文本框
--radiolist title [tag item status]   带有状态的单选列表菜单,可以表明选项是否被选定
--separate-output   为多选列表和单选列表菜单返回按行分开的选项
--sorry text   “对不起”消息框
--textbox file [width] [height]   显示file的内容的文本框,可以指定width和height
--title title   为对话窗口的TitleBar区域指定一个标题
--warningyesno text   带有Yes和No按钮的警告消息框
--warningcontinuecancel text 带有Continue和Cancel按钮的警告消息框
--warningyesnocancel text 带有Yes、No和Cancel按钮的警告消息框
--yesno text 带有Yes和No按钮的提问框
--yesnocancel text 带有Yes、No和Cancel按钮的提问框

checklist和radiolist部件允许你在列表中定义单独的选项以及它们默认是否选定,如下面的例子:

kdialog --checklist "Items I need" 1 "Toothbrush" on 2 "Toothpaste" off 3 "Hair brush" on 4 "Deodorant" off 5 "Slippers" off

当按下回车键时,kdialog窗口就和选定选项一起出现了。当单击OK或Cancel按钮时, kdialog命令会将每个标号作为一个字符串值返回到STDOUT(这些就是你在输出中看到的"1" 和"3")。脚本必须能解析结果值并将它们和原始值匹配起来。

2.1.2 使用kdialog

可以在shell脚本中使用kdialog窗口部件,方法类似于dialog部件。最大的不同是kdialog 窗口部件用STDOUT来输出值,而不是STDERR。

下面这个脚本将之前创建的系统管理菜单转换成KDE应用:

2.2 GNOME环境

GNOME图形化环境支持两种流行的可生成标准窗口的包:
  • gdialog
  • zenity

2.2.1 zenity部件

zenity允许用命令行选项创建不同的窗口部件,如下所示:

--calendar 显示一整月日历
--entry 显示文本输入对话窗口
--error 显示错误消息对话窗口
--file-selection 显示完整的路径名和文件名对话窗口
--info 显示信息对话窗口
--list 显示多选列表或单选列表对话窗口
--notification 显示通知图标
--progress 显示进度条对话窗口
--question 显示yes/no对话窗口
--scale 显示可调整大小的窗口
--text-info 显示含有文本的文本框

--warning 显示警告对话窗口


2.2.2 在脚本中使用zenity

在将系统管理菜单从kdialog迁移到zenity的过程中,需要对部件定义做大量的工作。
由于zenity并不支持菜单对话窗口,我们改用单选列表窗口来作为主菜单。 该单选列表用了两列,每列都有一个标题:第一列包含用于选择的单选按钮,第二列是选 项文本。单选列表也不用选项里的标号。当选定一个选项时,该选项的所有文本都会返回到 STDOUT。这会让case命令的内容丰富一些。必须在case中使用选项的全文本。如果文本中有任何空格,你需要给文本加上引号。
发表评论
评论通过审核后显示。