对话UNIX:使用Shell脚本创建好的图形应用程序
简介: 命令行不适合于每一位用户。事实上,一些用户可能仅在握着鼠标时才感到舒服。要仅使用 shell 来满足这些用户或构建桌面应用程序,可以向您的脚本添加一些 GUI。这里是一些具体做法。
如果您走进一个拥挤的机房,可能会听到有关 “shebangs”、斜线、点、根、管道、端口等等这个那个的闲聊。如果讲到 UNIX?,您无疑会理解本地术语 — 有关 UNIX 的缩略词、命令名、快捷键、选项、文件名和方言 — 且有宾至如归的感觉。与其他艺术工作者一样,UINX 用户拥有广泛的术语来描述其工作细节。
并非每个人都探讨 UNIX;事实上,有些人可能发现命令行很复杂,令人却步。此外,您可能不希望将全部命令行寄托给临时或无经验的用户。要帮助那些不习惯使用命令行的人,或构建围绕 shell 的自定义解决方案,您可以为您的脚本构建 GUI。有了这样的工具 — <font face="Courier New" size="2">dialog</font>
和 Zenity 是两个值得一提的工具您就可以使用对话框、文件浏览器和其他常见的 “windowing” 控件和技术来与您的用户交互。事实上,对话框提供更多自然对话:您提出问题,请求响应,并相应地予以响应。
本期的 “对话 UNIX” 探讨 <font face="Courier New" size="2">dialog</font>
和 Zenity,并展示如何将任何脚本转化成一个令人信服的 GUI 应用程序。对于传统的、基于文本的界面使用 <font face="Courier New" size="2">dialog</font>
,Zenity 提供现代风格的视窗化桌面。
向任何 shell 脚本添加对话框
一个命令行实用程序通常提供足够的选项来完全控制每个调用。一些 DOS 命令可能启用或禁用一个特性,而其他 DOS 命令可能处理参数,比如名称列表。在命令行,您将(几乎)所有信息呈现在前面,然后执行任务。图形应用程序很不同。选择是通过菜单、复选框和文件浏览器做出的。一个图形应用程序接受一点信息,处理它,然后通常要求获得更多信息。据说 GUI 应用程序是事件驱动的。
<font face="Courier New" size="2">dialog</font>
实用程序跨越两个世界。当您需要来自用户的输入时调用该实用程序,然后返回到您的脚本继续处理提供的任何数据。换言之,如果您写一个脚本来使用 <font face="Courier New" size="2">dialog</font>
,就有可能忽略命令行参数,而是使用 <font face="Courier New" size="2">dialog</font>
在必要时发出提示信息。
如果您的系统缺少 <font face="Courier New" size="2">dialog</font>
实用程序,您可以轻松使用当前版本自带的包管理器来安装它,或者您可以直接通过源代码编译它。例如,如果您的系统使用 Aptitude,您可以通过如下命令安装 <font face="Courier New" size="2">dialog</font>
:
sudo apt-get install dialog |
否则就要通过源代码编译,可以下载维护人员 Thomas Dickey 的 Web 站点上的代码(参见 参考资料)并运行典型的三个命令:<font face="Courier New" size="2">./configure && make && make install</font>
:
$ wget http://invisible-island.net/datafiles/release/dialog.tar.gz $ tar xzf dialog.tar.gz $ cd dialog-1.1-20100428 $ ./configure $ make $ sudo make install |
安装完成之后,您的路径中应当会有一个名为 <font face="Courier New" size="2">dialog</font>
的新实用程序。输入 <font face="Courier New" size="2">man dialog</font>
来查看捆绑文档。
<font face="Courier New" size="2">dialog</font>
使用起来很简单:它仅是另一个 UNIX 命令。您使用命令选项显示您选择的对话框,然后捕获结果并基于该值执行一些逻辑。<font face="Courier New" size="2">dialog</font>
的一些变体直接将命令结果放在特殊的 shell 状态变量 <font face="Courier New" size="2">$?</font>
中,您应当在 <font face="Courier New" size="2">dialog</font>
命令退出后立即保存或询问该变量(因为随后的一个命令会立即改变其值)。另外,通常更为复杂的 <font face="Courier New" size="2">dialog</font>
命令变体同时设置 shell 状态变量并生成其他结果。为将事情简单化,<font face="Courier New" size="2">dialog</font>
提供 <font face="Courier New" size="2">--stdout</font>
选项来将其结果发出到标准输出,因而便于通过命令求值捕获数据(带左引号的命令和赋值语句的组合)。
例如,<font face="Courier New" size="2">dialog --yesno</font>
命令是最简单的变体之一。它提出一个问题,提示做出是或否的响应,并返回 <font face="Courier New" size="2">$?</font>
中的 <font face="Courier New" size="2">0</font>
或 <font face="Courier New" size="2">1</font>
,具体取决于用户选择了 “Yes” 还是 “No”。您可以测试 <font face="Courier New" size="2">$?</font>
的值并执行一些条件代码。这里是您可以添加到 shell 脚本的一个工作代码段:
dialog --yesno "Do you want to continue?" 0 0 rc=$? if [ "${rc}" == "0" ]; then echo Yes else echo No fi |
<font face="Courier New" size="2">--yesno</font>
选项需要至少三个参数:问题文本以及对话框本身的高度和宽度,后者用行和列度量。如果您不需要特定尺寸,总是可以为高度或宽度使用 <font face="Courier New" size="2">0</font>
,以自动调整对话框大小。(还有相对于窗口左下角放置窗口的选项。)图 1 展示运行中的 <font face="Courier New" size="2">--yesno</font>
。
图 1. --yesno 操作
<font face="Courier New" size="2">dialog</font>
选项 <font face="Courier New" size="2">--calendar</font>
呈现一个日历来允许用户选择特定日期。如果用户选择一个日期,然后单击 OK,命令返回 <font face="Courier New" size="2">0</font>
。但是,如果用户单击 Cancel,命令返回 <font face="Courier New" size="2">1</font>
。此外,如果用户单击 OK,命令将选定日期发出为标准输出。这里是使用命令求值产生日期的一个例子:
RESULT=`dialog --stdout --title "CALENDAR" --calendar "Please choose a date..." 0 0 9 1 2010` retval=$? |
<font face="Courier New" size="2">--title</font>
选项使用下一个参数来将一个标题添加到对话框,且可用于任何 <font face="Courier New" size="2">dialog</font>
命令。非常像 <font face="Courier New" size="2">--yesno</font>
,您提供一些文本来提示用户。接下来,选项 <font face="Courier New" size="2">0 0</font>
再次指定自动高度和宽度,选项 <font face="Courier New" size="2">9 1 2010</font>
分别指示日历中显示的初始日、月和年。选项卡和箭头键改变日历并选择一个日期。对话框退出后,如果 <font face="Courier New" size="2">retval</font>
是 <font face="Courier New" size="2">0</font>
,<font face="Courier New" size="2">RESULT</font>
的值就是选定的日期。图 2 显示日历对话框。
图 2. 日历对话框
<font face="Courier New" size="2">dialog</font>
命令提供通常在图形应用程序中找到的大部分控件:
<font face="Courier New" size="2">--infobox</font>
仅仅展示信息:它不要求任何输入。信息框仍然只是简单地在屏幕上。要延长其显示,在它和下一个命令之前置入一个<font face="Courier New" size="2">sleep</font>
命令。<font face="Courier New" size="2">--input</font>
收集单一输入响应。您可能会使用该命令来收集您的用户的姓名或邮政编码。<font face="Courier New" size="2">--textbox</font>
显示一个文本文件的内容。如果文件超出对话框的垂直高度,一个控件支持简单的向上和向下滚动。<font face="Courier New" size="2">--menu</font>
和<font face="Courier New" size="2">--radiolist</font>
提供一个选择列表,供用户进行选择。两种对话框在功能上是等同的,但是略有不同的视觉风格,以更好地模拟一个 GUI 可能展示的东西。特别地,<font face="Courier New" size="2">--radiolist</font>
命令呈现<font face="Courier New" size="2">( )</font>
来模拟单选按钮。<font face="Courier New" size="2">--checklist</font>
显示用户可单独启用或禁用的一个项目列表。
每个 <font face="Courier New" size="2">dialog</font>
变体的输出不同,或是一个单一值,或是一列由空格分隔的带引号值。例如,<font face="Courier New" size="2">--checklist</font>
是用于选择一个或多个选项的一个不错的控件,它发出一列带引号值,其中每个值与一个启用的选项相关。下面演示了一个操作示例:
RESULT=`dialog --stdout --checklist "Enable the account options you want:" 10 40 3 \ 1 "Home directory" on \ 2 "Signature file" off \ 3 "Simple password" off` |
行 1、2 和 3 结尾的反斜杠(<font face="Courier New" size="2">\</font>
)是延续标记;从 <font face="Courier New" size="2">RESULT</font>
到 <font face="Courier New" size="2">off`</font>
的一切内容是一个命令。如果用户启用了 Home directory 和 Simple password,<font face="Courier New" size="2">$RESULT</font>
将会是 <font face="Courier New" size="2">"1" "3"</font>
。<font face="Courier New" size="2">--checklist</font>
的参数是高度和宽度,任何时间内的列表元数量(如果有些项目被挡住,您可以通过滚动查看这些项目),以及清单选项(其中每个选项是一个值)、一个描述、在最初启用或禁用该选项。
您可以随时输入 <font face="Courier New" size="2">dialog --help</font>
来查看常规列表,输入 <font face="Courier New" size="2">dialog</font>
来查看特定选项。<font face="Courier New" size="2">dialog</font>
有无数用法。