简介: 命令行不适合于每一位用户。事实上,一些用户可能仅在握着鼠标时才感到舒服。要仅使用 shell 来满足这些用户或构建桌面应用程序,可以向您的脚本添加一些 GUI。这里是一些具体做法。
如果您走进一个拥挤的机房,可能会听到有关 “shebangs”、斜线、点、根、管道、端口等等这个那个的闲聊。如果讲到 UNIX®,您无疑会理解本地术语 — 有关 UNIX 的缩略词、命令名、快捷键、选项、文件名和方言 — 且有宾至如归的感觉。与其他艺术工作者一样,UINX 用户拥有广泛的术语来描述其工作细节。
并非每个人都探讨 UNIX;事实上,有些人可能发现命令行很复杂,令人却步。此外,您可能不希望将全部命令行寄托给临时或无经验的用户。要帮助那些不习惯使用命令行的人,或构建围绕 shell 的自定义解决方案,您可以为您的脚本构建 GUI。有了这样的工具 — dialog 和 Zenity 是两个值得一提的工具(参见 参考资料) — 您就可以使用对话框、文件浏览器和其他常见的 “windowing” 控件和技术来与您的用户交互。事实上,对话框提供更多自然对话:您提出问题,请求响应,并相应地予以响应。
本期的 “对话 UNIX” 探讨 dialog 和 Zenity,并展示如何将任何脚本转化成一个令人信服的 GUI 应用程序。对于传统的、基于文本的界面使用 dialog,Zenity 提供现代风格的视窗化桌面。
向任何 shell 脚本添加对话框
一个命令行实用程序通常提供足够的选项来完全控制每个调用。一些 DOS 命令可能启用或禁用一个特性,而其他 DOS 命令可能处理参数,比如名称列表。在命令行,您将(几乎)所有信息呈现在前面,然后执行任务。图形应用程序很不同。选择是通过菜单、复选框和文件浏览器做出的。一个图形应用程序接受一点信息,处理它,然后通常要求获得更多信息。据说 GUI 应用程序是事件驱动的。
dialog 实用程序跨越两个世界。当您需要来自用户的输入时调用该实用程序,然后返回到您的脚本继续处理提供的任何数据。换言之,如果您写一个脚本来使用 dialog,就有可能忽略命令行参数,而是使用 dialog 在必要时发出提示信息。
如果您的系统缺少 dialog 实用程序,您可以轻松使用当前版本自带的包管理器来安装它,或者您可以直接通过源代码编译它。例如,如果您的系统使用 Aptitude,您可以通过如下命令安装 dialog:
- sudoapt-getinstalldialog
否则就要通过源代码编译,可以下载维护人员 Thomas Dickey 的 Web 站点上的代码(参见 参考资料)并运行典型的三个命令:./configure && make && make install:
- $wgethttp:
- $tarxzfdialog.tar.gz
- $cddialog-1.1-20100428
- $./configure
- $make
- $sudomakeinstall
安装完成之后,您的路径中应当会有一个名为 dialog 的新实用程序。输入 man dialog 来查看捆绑文档。
dialog 使用起来很简单:它仅是另一个 UNIX 命令。您使用命令选项显示您选择的对话框,然后捕获结果并基于该值执行一些逻辑。dialog 的一些变体直接将命令结果放在特殊的 shell 状态变量 $? 中,您应当在 dialog 命令退出后立即保存或询问该变量(因为随后的一个命令会立即改变其值)。另外,通常更为复杂的 dialog 命令变体同时设置 shell 状态变量并生成其他结果。为将事情简单化,dialog 提供 --stdout 选项来将其结果发出到标准输出,因而便于通过命令求值捕获数据(带左引号的命令和赋值语句的组合)。
例如,dialog --yesno 命令是最简单的变体之一。它提出一个问题,提示做出是或否的响应,并返回 $? 中的 0 或 1,具体取决于用户选择了 “Yes” 还是 “No”。您可以测试 $? 的值并执行一些条件代码。这里是您可以添加到 shell 脚本的一个工作代码段:
- dialog--yesno"Doyouwanttocontinue?"00
- rc=$?
-
if["${rc}"=="0"];then
- echoYes
-
else
- echoNo
- fi
--yesno 选项需要至少三个参数:问题文本以及对话框本身的高度和宽度,后者用行和列度量。如果您不需要特定尺寸,总是可以为高度或宽度使用 0,以自动调整对话框大小。(还有相对于窗口左下角放置窗口的选项。)图 1 展示运行中的 --yesno。
图 1. --yesno 操作
dialog 选项 --calendar 呈现一个日历来允许用户选择特定日期。如果用户选择一个日期,然后单击 OK,命令返回 0。但是,如果用户单击 Cancel,命令返回 1。此外,如果用户单击 OK,命令将选定日期发出为标准输出。这里是使用命令求值产生日期的一个例子:
- RESULT=`dialog--stdout--title"CALENDAR"
- --calendar"Pleasechooseadate..."00912010`
- retval=$?
--title 选项使用下一个参数来将一个标题添加到对话框,且可用于任何 dialog 命令。非常像 --yesno,您提供一些文本来提示用户。接下来,选项 0 0 再次指定自动高度和宽度,选项 9 1 2010 分别指示日历中显示的初始日、月和年。选项卡和箭头键改变日历并选择一个日期。对话框退出后,如果 retval 是 0,RESULT 的值就是选定的日期。图 2 显示日历对话框。
图 2. 日历对话框
dialog 命令提供通常在图形应用程序中找到的大部分控件:
--infobox 仅仅展示信息:它不要求任何输入。信息框仍然只是简单地在屏幕上。要延长其显示,在它和下一个命令之前置入一个 sleep 命令。
--input 收集单一输入响应。您可能会使用该命令来收集您的用户的姓名或邮政编码。
--textbox 显示一个文本文件的内容。如果文件超出对话框的垂直高度,一个控件支持简单的向上和向下滚动。
--menu 和 --radiolist 提供一个选择列表,供用户进行选择。两种对话框在功能上是等同的,但是略有不同的视觉风格,以更好地模拟一个 GUI 可能展示的东西。特别地,--radiolist 命令呈现 ( ) 来模拟单选按钮。
--checklist 显示用户可单独启用或禁用的一个项目列表。
每个 dialog 变体的输出不同,或是一个单一值,或是一列由空格分隔的带引号值。例如,--checklist 是用于选择一个或多个选项的一个不错的控件,它发出一列带引号值,其中每个值与一个启用的选项相关。下面演示了一个操作示例:
- RESULT=`dialog--stdout
- --checklist"Enabletheaccountoptionsyouwant:"10403/
- 1"Homedirectory"on/
- 2"Signaturefile"off/
- 3"Simplepassword"off`
行 1、2 和 3 结尾的反斜杠(/)是延续标记;从 RESULT 到 off` 的一切内容是一个命令。如果用户启用了 Home directory 和 Simple password,$RESULT 将会是 "1" "3"。--checklist 的参数是高度和宽度,任何时间内的列表元数量(如果有些项目被挡住,您可以通过滚动查看这些项目),以及清单选项(其中每个选项是一个值)、一个描述、在最初启用或禁用该选项。
您可以随时输入 dialog --help 来查看常规列表,输入 dialog 来查看特定选项。dialog 有无数用法。
有像素?使用 Zenity。
Zenity 是 UNIX 桌面,如同 dialog 是简单的终端窗口。您可以使用 Zenity 从任何 shell 脚本打开 GTK+ 对话框。事实上,Zenity 与 dialog 有着许多相同的功能;惟一的区别在于,Zenity 在一个 X Window System 环境中工作。Zenity 与 GNOME 相捆绑。如果您不运行 GNOME,可以单独安装 Zenity(但是,也要安装大量 GTK+ 库)。您还可以从 GNOME 项目页面下载 Zenity 的源代码(参见 参考资料 获取链接)。
下面是一个简单的例子。命令为:
- zenity--question--text"Doyouwanttocontinue?"
生成的结果如 图 3 所示。(用于演示的机器在运行 Ubuntu 10。)如果您单击 OK,命令返回 0。否则,它返回 1。
图 3. 一个简单问题
如同 dialog,Zenity 有很多选项 — 甚至比 dialog 还多 — 但是选项命名贴切,因而不言自明。您可能发现 Zenity 比 dialog 更有优势,特别是由于大部分计算机用户都有某种 X 桌面。
Zenity 提供与 dialog 相同的许多控件。这里是收集名称的一个代码段:
- ENTRY=`zenity--entry--text"Pleaseenteryourname"
- --entry-text"Yourname"--title"Enteryourname"
-
if[$?==0];then
- zenity--info--text"Hello$ENTRY/!"
- fi
再次说明,如果 zenity 的退出代码是 0,那么 ENTRY 有某人的姓名。这里是为使用 Zenity 而重写后的日历示例:
- DATE=`zenity--calendar--day"9"--month"1"--year"2010"--format"%Y-%m-%d"
-
if[$?==0];then
- echo$DATE
- fi
尽管 Zenity 更详细一点 — 例如,对于年、月、日有单独的选项 — 其他 DOS 命令使您免于记住精确的参数使用顺序。Zenity 的日历还允许您指定输出格式,即使用标准 strftime() 代码。该命令的结果类似于 2010-1-9,它表示 2010 年 1 月 9 日。
Zenity 还提供一个过程表来展示一个操作的状态。它从标准输入逐行读取数据。如果一个行的前缀是井号(#),文本被更新为该行文本。如果一个行仅包含一个数字,百分比被更新为该数字。清单 1 展示 Zenity 文档中的一个示例。
清单 1. Zenity 过程表
-
#!/bin/sh
- (
- echo"10";sleep1
- echo"#Updatingmaillogs";sleep1
- echo"20";sleep1
- echo"#Resettingcronjobs";sleep1
- echo"50";sleep1
- echo"Thislinewilljustbeignored";sleep1
- echo"75";sleep1
- echo"#Rebootingsystem";sleep1
- echo"100";sleep1
- )|
- zenity--progress/
- --title="UpdateSystemLogs"/
- --text="Scanningmaillogs..."/
- --percentage=0
-
-
if["$?"=-1];then
- zenity--error/
- --text="Updatecanceled."
- fi
sub-shell(包含在括号中)执行一系列任务 — 在这个人为例子中 albeit sleep 延迟 — 且通过一个管道将输出发出到一个 Zenity 过程表。在每一步之前,sub-shell 发出一个数字来推进过程表,每个 --percentage 0 起始于 0,然后发出一个以 # 开头的字符串来改变状态消息。因此,过程表沿着步骤标记脚本工作。如果 Zenity 的退出代码是 -1,单击的是 Cancel 按钮。
再次说明,要使用 dialog 或 Zenity,用对话框替换您之前引用过命令行参数的代码。用一个小创意,您可以将您的 shell 脚本转化为一等桌面公民。
其他高级工具
有些时候,您可能发现您的需求超过了 shell 脚本以及 dialog 和 Zenity 工具的功能范围之外。在那些实例中,您可能转向 C/C++ 并为桌面构建本机应用程序,但是您还可以使用高级脚本语言和许多强大的 GUI 框架的语言绑定。
一个组合是 Ruby 脚本语言和 wxWidgets 框架的 Ruby 绑定。Ruby 是面向对象的、富于表现力的且简洁的,运行于大部分操作系统之上。wxWidgets 框架还可用于每个主流平台,包括 Mac OS X、Windows®、Linux® 和 UNIX。由于两者都是可移植的,您可以用 Ruby 编写一个应用程序一次,然后随处运行它。另一个更简单的选择是 Shoes。尽管不如 wxWidgets 丰富,Shoes 学习和使用起来相当简单。清单 2 使用 70 行代码实现了一个计算器。
清单 2. 用 Shoes 实现的一个计算器
-
classCalc
- definitialize
- @number=0
- @previous=nil
- @op=nil
- end
-
- defto_s
- @number.to_s
- end
-
- (0..9).eachdo|n|
- define_method"press_#{n}"do
- @number=@number.to_i*10+n
- end
- end
-
- defpress_clear
- @number=0
- end
-
- {'add'=>'+','sub'=>'-','times'=>'*','div'=>'/'}.eachdo|meth,op|
- define_method"press_#{meth}"do
-
if@op
- press_equals
- end
- @op=op
- @previous,@number=@number,nil
- end
- end
-
- defpress_equals
- @number=@previous.send(@op,@number.to_i)
- @op=nil
- end
- end
-
- number_field=nil
- number=Calc.new
- Shoes.app:height=>250,:width=>200,:resizable=>falsedo
- background"#EEC".."#996",:curve=>5,:margin=>2
-
- stack:margin=>2do
-
- stack:margin=>8do
- number_field=parastrong(number)
- end
-
- flow:width=>218,:margin=>4do
- %w(789/456*123-0Clr=+).eachdo|btn|
- buttonbtn,:width=>46,:height=>46do
- method=casebtn
- when/[0-9]/;'press_'+btn
- when'Clr';'press_clear'
- when'=';'press_equals'
- when'+';'press_add'
- when'-';'press_sub'
- when'*';'press_times'
- when'/';'press_div'
- end
-
- number.send(method)
- number_field.replacestrong(number)
- end
- end
- end
- end
- end
对 Ruby 和 Shoes 的介绍不在本文讨论范围之内,但是这里是一些最重要的构造:
大多数 Ruby 类 Calc 使用 Ruby 的元编程功能,在运行时为所有数字键和数学操作键定义功能。
代码开头 Shoes.app... 创建计算器的 GUI,为其呈现布局和按钮。Shoes 提供两个容器来装配布局:stack 和 flow。一个 stack 是元素的一个垂直堆栈,其中每个元素直接放在前一个元素下面。一个 flow 尽量紧密地包裹元素,直至它达到其边框局限,然后包装其余的元素。(您可以将一个堆栈看作是一个 HTML <div>,将一个流看作 HTML <p>。)您可以使用 Ruby 块创建一个堆栈或一个流。
最里面的 flow 快循环创建应用程序中的所有按钮,并有效地将每个按钮绑定到其方法。(case 语句返回一个方法名称;number.send(method) 行调用实例化计算器上的那个方法。)
number_field.replace strong(number) 行通过最新计算结果更新计算器显示。发出 number 致使类调用其自己的 to_s (“to string”) 方法。
其他脚本语言拥有类似的库,且 Ruby 本身有更多选择,包括 Ruby Cocoa,可使用 Ruby 在 Mac OS X 上开发 Cocoa 应用程序。选择您喜欢的开源脚本语言,找到一个轻量级 GUI 工具包,然后开始编码。
您不需要讨厌的编译器!
如果您已经掌握了 shell 脚本编写,将您的工作与 dialog 或 Zenity 结合起来,以增加互操作性。如果您需要的编程功能比 shell 提供的更多,考虑 Ruby 或 Python 这样的语言以及任何窗口工具包。您无需一个编译器来编写良好的桌面应用程序。
关于作者
Martin Streicher 是一位 Ruby on Rails 的自由开发人员和 Linux Magazine 的前任主编。Martin 毕业于 Purdue University 并获得计算机科学学位,从 1986 年起他一直从事 UNIX 类系统的编程工作。他喜欢收集艺术品和玩具。
相关推荐
在"Swift-shell脚本和命令行应用程序的实时原生微型图形用户界面"这个主题中,我们将探讨如何利用Swift构建具有图形用户界面(GUI)的命令行工具。 首先,让我们理解什么是shell脚本。Shell脚本是Unix或类Unix操作...
Shell脚本是一种在Unix/Linux操作系统中使用的编程语言,用于自动化一系列命令执行任务。它是用户与操作系统交互的一种强大工具,尤其在系统管理、文件操作和任务调度方面发挥着重要作用。 入门Shell脚本,首先要...
- **通过第三方系统的X应用**:探讨了如何在远程主机上运行图形界面程序。 - **用户-Profile项**和**根-Profile项**:介绍了X客户端如何设置环境变量。 - **弹出一个临时的根窗口**:如何创建一个临时的图形界面窗口...
8. **执行安装脚本**:使用`runInstaller`命令启动Oracle的图形化安装程序,脚本会自动输入必要的信息,如产品选项、安装类型、系统身份验证等。 9. **创建数据库**:安装完成后,脚本会继续创建一个默认的数据库...
在压缩包内的文件名称"luci-app-webshell",可以推断这是一个LuCI的应用程序包,用于添加网页Shell功能到OpenWrt。"luci-app-"是LuCI应用的标准前缀,"webshell"是该应用的具体名称,即网页Shell模块。 这个模块...
本文将深入探讨如何在Linux环境中利用Shell脚本实现图形化桌面的交互式功能,特别是通过`msgbox`、`select`命令以及`dialog`工具来创建用户友好的脚本界面。 首先,`msgbox`通常是一个非标准的Shell命令,它属于...
本教程将分为两大部分,分别介绍Linux的基础知识和安装过程,以及Linux命令与Shell脚本的详细应用。 一、Linux简介及安装 1. Linux发行版:Linux并不是单一的操作系统,而是一系列基于Linux内核的开源操作系统发行...
### Shell脚本的介绍与教学 #### shell概览与作用 **shell脚本**是一种用于自动化...以上是shell脚本的基础介绍及部分核心知识点的详解,通过学习和实践这些内容,可以帮助用户更好地利用shell脚本来提升工作效率。
### Shell脚本入门教程知识点详解 #### 一、Shell编程的重要性与应用场景 ...通过上述内容的学习,您可以更好地理解和掌握Shell脚本的基础知识和技术要点,为进一步深入学习和应用Shell脚本打下坚实的基础。
Platypus是一个开发人员工具,可以从命令行脚本(例如Shell脚本或Python,Perl,Ruby,Tcl,JavaScript和PHP程序)创建本机Mac应用程序。这是通过将脚本与运行脚本的应用二进制文件包装在macOS 应用程序捆绑包中来...
Shell脚本是Linux系统中的一种批处理程序,它由一系列的命令组成,这些命令可以按照特定顺序执行,从而实现自动化任务。在`oraclep安装shell脚本`中,可能包含了如下步骤: 1. **环境准备**:检查系统版本、硬件...
执行Shell脚本需要先给脚本文件添加执行权限,使用命令chmod +x script.sh,然后使用命令./script.sh执行脚本。 5. 变量 在Shell脚本中,变量是存储数据值的容器。局部变量仅在声明它们的作用域内有效,而全局变量...
为了更好地学习 C Shell 和相关的脚本编写技术,书中还推荐了一些额外的学习资源,以便读者可以深入探索更高级的主题。 #### 三、手册使用指南 本章节简要介绍了如何有效地利用这本书来学习 C Shell 脚本编写技巧。...
在多平台环境中,Shell脚本提供了一致性和灵活性,尤其在处理结构化数据(如XML、JSON)或需要图形用户界面的应用中。 Shell脚本是系统工程师和高级程序员不可或缺的技能之一,它不仅是系统自动化的核心路径,还是...
"基于当前窗口和选定文本执行操作的Shell脚本"是指一种特殊类型的脚本,这种脚本能够捕获用户在终端或GUI应用程序中选中的文本,并根据该文本执行特定的操作。这样的功能在数据处理、文本分析或者自动化测试中非常...
- **图形用户界面**:Shell脚本不支持创建GUI,因此不适合开发需要图形界面的应用程序。 #### 五、Shell脚本实例 下面是一些基本的Shell脚本示例: 1. **文件备份脚本**: ```bash #!/bin/bash # 文件备份脚本...
然而,直接在shell脚本中创建图形用户界面并不常见,因为它们通常更适合命令行操作。gtkdialog库为此提供了一种解决方案,使得非程序员或不熟悉复杂GUI编程的人也能在shell脚本中创建具有图形元素的应用。 压缩包内...
- **重要性**: 使用Windows Shell编程可以提升应用程序与操作系统的整合度,让程序更加贴近用户的需求,例如自定义开始菜单、创建特殊的文件夹类型等。 - **适用人群**: 适合希望深入了解Windows系统内部运作机制的...