Going Graphical -- The dialog Utility
在我们结束shell脚本讨论之前,有一个虽然不是shell的一部分但却有更多的特性,尤其对于shell编程来说使用也非常普遍,因此我们将在此对它做一番了解。
如果我们知道我们的脚本将只在linux控制台运行,有一种简洁的方法可以用来改善我们的脚本特色,它就是dialog,一个实用程序命令。该命令虽然使用文本模式图形和颜色,但看起来依旧有着令人愉悦的图形色彩。
整个dialog的思想都很简单——只是一个有着种类繁多的参数和选项的单一程序,而且这些参数和选项允许你用来显示不同种类的图形方框,所显示的范围也只是有着简单的Yes/No的输入方框以及甚至还拥有菜单选择。这个工具一般在用户进行输入操作之后返回,并且返回的结果可以由返回的状态或者是通过取回标准错误流输入的文本得到。
在我们深入了解之前,先让我们看一个简单的dialog运用。我们直接从命令行通过使用dialog创建一个简单的消息框:
dialog --msgbox "Hello World" 9 18
之后在屏幕上将显示一个带有OK对话框的图形消息框。
既然我们已经知道了dialog的操作是如此简单,之后让我们尽可能地了解更多与之相关的内容。下表为我们描述了我们可以创建的dialog的主要类型:
Type | Option Used to Create Type | Meaning |
Check boxes | --checklist | 允许我们显示列表项,且每一个都能被单独选择 |
Info boxes | --infobox | 不用清屏就能直接返回的简单对话框 |
Input boxes | --inputbox | 允许用户以文本方式输入 |
Menu boxes | --menu | 允许用户从一列中选择单一的一项 |
Message boxes | --msgbox | 向用户显示一条带有OK按钮的信息 |
Radio selection boxes | --radiolist | 允许用户从一列中选择一个选项 |
Text boxes | --textbox | 允许我们在一个有滚动轴的框中显示文件内容 |
Yes/No boxes | --yesno | 允许你问一个问题,之后用户可以选择yes或no |
一些额外的dialog对话框同样也是很有用的(比如计量器和密码输入对话框)。如果你想要了解更多不太常用的dialog类型,可以查阅相关的手册指南。
为了得到允许文本输入或选择的对话框的任何类型的输出,我们不得不捕获标准错误流,通常我们都直接将它送到一个临时文件中,之后再对它进行处理。而为了得到yes/no类型问题的结果,我们只需看退出代码,通常设计良好的程序都将返回0代表成功,而返回1则代表失败。
所有的dialog类型都有许多附加参数来用于控制,比如dialog所呈现的大小以及形状。我们在下表列出了每一种类型所需要的不同参数,之后我们将在命令行中示范操作他们中的一部分。最后,你将会看到在一个简单的包含几个dialog的程序。
Dialog Type | Parameters |
--checklist | text height width list-height [tag text status]... |
--infobox | text height width |
--inputbox | text height width [initial string] |
--menu | text height width menu-height [tag item]... |
--msgbox | text height width |
--radiolist | text height width list-height [tag text status]... |
--textbox | filename height width |
--yesno | text height width |
此外,所有的diglog类型都可以携带几个选项,我们不会在此将它们一一列出,除了需要注意这两个:
若想了解所有的选项,请查阅相关的手册指南。
下面让我来看一下一个有点复杂的例子。一旦你理解了这个例子,其他的dialog实例将变得容易。在这个例子中,你创建了一个带有标题“Check me”以及指令“Pick Numbers”的清单类型对话框。这个对话框高15个字符,宽25个字符,并且每个选项都要占领3个字符的高度。最后,你至少在显示这些列出的选项时,需要沿着一个默认的on/off选择。
原理:
在这个示例中,参数--checklist指定了你将创建一个清单类型对话框。之后你使用--title选项来设置标题“Check me”,而接下来的参数则提示“Pick Numbers”的信息。然后你开始设置对话框的大小,15行高25字符宽,并有3行高的高度被用于菜单的显示。这虽然不是一个完美的尺寸,但足够你看到所有的东西都被呈现出来。
选项的使用看起来有点错综复杂,但你需要全部记住的只是每个菜单项目都只有三个数值:标号、文本以及状态。第一个项目为1,显示为“one”并且设置为“off”。之后的菜单项目2显示为“two”,设置为“on”,即被此项被选中了。最后菜单项目3显示为“three”,设置为“off”。
很容易,对不对?我们只需尝试将他们在命令行中运行就可以轻易地看出它们是怎样被使用的。为了将这些对话框放入一个程序中,我们需要能够访问用户所输入的结果,这是非常容易的。只需为文本输入将标准错误流重定向,或者检查系统环境变量$?,这样你就可以再次调用先前命令的退出状态。
下面我们看一个使用dialog的更复杂一些的例子。
我们先编写一个简单的程序questions,它用来接受用户响应的记录:
1.开始先显示一个简单的对话框以告诉用户发生了什么,你不需要得到相关的结果或获取任何用户输入,因此我们可以这样简单地编写:
# Ask some questions and collect the answer
dialog --title "Questionnaire" --msgbox "Welcome to my simple survey" 9 18
2.通过一个简单的yes/no对话框询问用户是否继续进行。通过使用环境变量$?来检查用户所选择的到底是yes(返回代码0)还是no。如果他不想继续进行,我们就会在退出前使用一个简单的不需要用户有输入的信息对话框:
if [ $? != 0 ]; then
dialog --infobox "Thank you anyway" 5 20
sleep 2
dialog --clear
exit 0
fi
3.通过一个输入框询问用户的名字。重定向标准错误流2到一个临时文件_1.txt中,之后通过变量Q_NAME来进行处理:
Q_NAME=$(cat _1.txt)
4.在此处你将设置菜单项目为四个不同的选项,之后你再次重定向标准错误流并将它置入一个变量中:
Q_MUSIC=(cat _1.txt)
5.根据所获得的变量Q_MUSIC得到存储在临时文件_1.txt中的用户所选择的数字,你可以这样来设置结果:
dialog --title "Likes Classical" --msgbox "Good choice!" 12 25
else
dialog --title "Doesn't like Classical" --msgbox "What a shame!" 12 25
fi
6.最后,清除最终的对话框,之后退出程序:
dialog --clear
exit 0
OK,现在我们可以通过shell编程只使用shell脚本来显示一个简单GUI程序了。