图形化桌面 Korn Shell

可移植性和普及性是开发代码时需要考虑的两个重要特性。使用具有良好定义和稳定的应用程序编程接口 (API) 的编程语言可以满足对可移植性的需求。具有庞大且成熟的安装基础的编程语言提供了普及性。虽然 Perl、Tcl/Tk、通用网关接口 (CGI) 和 Java 拥有庞大的安装基础,但它们并不适合某些项目。原因在于它们不一致的安装基础,这是由于缺乏明确定义或快速变化的 API。
Common Desktop Environment (CDE) 自带的 Desktop Korn Shell (DtKsh) 基于 ksh93 标准构建,并内置了 X、Xt、Motif、ToolTalk 和 CDE API。与 Perl 和 Tcl/Tk 不同,主要供应商通过 CDE 倡议构建并支持 DtKsh。使用 DtKsh,桌面程序员可以开发和/或原型化即插即用的图形用户界面 (GUI) 应用程序,这些应用程序在所有符合 CDE 标准的系统上都兼容,无需编译。虽然 DtKsh 应用程序为了可移植性而被解释执行,但它们可以轻松迁移到 C 中的 Motif 以提高性能。
Tcl/Tk 可以借助特殊的 Tcl/Tk 库移植到 C;然而,程序员在使用 C Tcl/Tk 库时与使用 Tcl/Tk shell 时一样处于不利地位,因为它们都具有非标准的应用程序编程接口。与 Tcl/Tk 不同,DtKsh 提供了一套完善的 API 集,程序员的知识可以从 C 语言扩展到 shell 编程。
在 AIX 中,/bin/ksh 是符合 XPG4 标准的 ksh88 版本。AIX 上 CDE 的 /usr/dt/bin/dtksh 基于更新的 ksh93 标准。ksh93 现在包括浮点数学、关联数组、新的字符串操作、分层变量、引用变量、使用附加共享库的开发者可扩展 API 以及字符类模式。
浮点数学:Korn Shell 变量可以被强制转换或定义为各种聚合数据类型。浮点数学是 Korn Shell 中的一项新功能,它支持十进制值的赋值和运算。以下示例定义了浮点变量 PI,然后为其赋值十进制值 3.14159。
typeset -F PI # define "PI" as a float PI = 3.14159
关联数组:关联数组允许使用字母数字字符串来寻址数组元素,而不是使用正整数索引。以下示例显示 SYSINFO 作为一个包含操作系统信息的数组。关联数组 SYSINFO 可以使用字母数字字符串 “os” 进行索引,以查找 AIX 的字符串值。
typeset -A SYSINFO # define "SYSINFO" as an # associative array SYSINFO["os"]=AIX新的字符串操作:ksh93 中引入了六个新的字符串操作。这些新操作提供了子字符串化和用替代项替换字符串模式。子字符串化允许提取较小的字符串,给定一个指示起始位置的偏移量,并可能给定其长度。
可以从给定起点按长度提取较大字符串的子字符串,或者可以通过从较大字符串内的偏移量开始并在字符串末尾停止来获取子字符串。以下显示了给定长度的子字符串
${variable:offset:length}
只需提供偏移量即可获取不定长度的子字符串。
${variable:offset}
可以对字符模式进行字符串替换,用于首次出现、重复出现、字符串开头(前缀)或字符串结尾(后缀)。用替代字符串替换模式的首次出现
${variable/pattern/string}
用替代字符串替换模式的所有出现
${variable//pattern/string}
用替代字符串替换模式前缀
${variable/#pattern/string}
用替代字符串替换模式后缀
${variable/%pattern/string}
BOX= # declare before assigning sub-members BOX.WIDTH = 80 BOX.HEIGHT = 24引用变量:引用允许一个变量指向与另一个变量相同的值;如下所示,两个变量都引用相同的值
# name reference typeset -n FOO=BAR FOO="Hello World" # print "Hello World" print ${BAR}桌面内置命令:Korn Shell 直接在 shell 中提供了一些标准的 X、Xt、Motif、POSIX 国际化和 CDE C 语言 API。从 shell 直接访问这些 API 为 DtKsh shell 应用程序提供了显着的运行时性能提升。使用标准的 X 和 Motif API,并对源代码进行一些语义更改,使得 DtKsh shell 脚本可以迁移到 C 并进行编译。
POSIX 国际化:Korn Shell 提供了 C 语言 POSIX 国际化 API catopen 和 catgets 的 shell 等效项。国际化 API 允许 shell 程序根据其语言更改其消息目录。国际化的 shell 脚本支持多语言。
字符类模式:shell 中的正则表达式通过预定义一组字符类模式得到增强。现在,我们可以使用 [[:class:]] 表示法轻松匹配某些字符类,其中 class 可以指定为 alnu、alpha、cntrl、digit、graph、lower、upper、print、punct、space 和 xdigit。
# only print files that # begin in upper case print [[:upper:]]* # old way print [A-Z]*
熟悉的 “Hello World” Motif 应用程序(如 清单 1 所示)实际上是用 DtKsh 而不是 C 编写的。与 C 类似,我们初始化顶层 shell 部件,然后开始构建 GUI 应用程序。清单 1 显示了一个使用熟悉的 XmCreateMessageDialog API 的标准 Motif 消息对话框。在 DtKsh 中,可以检索部件的句柄,可以管理和取消管理部件,并且可以创建回调。之后,程序通过 XtMainLoop 进入 Xt Intrinsic 的主循环,在那里它处理 X 协议事件。在本例中,单击“确定”按钮将是由事件循环处理的事件。

图 1. DtKsh 和 Motif “Hello World”
清单 1 中的 Motif “Hello World” DtKsh 应用程序可以通过一些小的更改轻松移植到 C,如 清单 2 所示。通过添加一些包含文件、定义一些变量、添加一些逗号和分号以及修饰一些参数,我们就得到了一个 C 程序。结果是 DtKsh shell 脚本与 C Motif 应用程序进行相同的 API 调用。
AIX 通过 GUI 构建器提供了一些额外的 DtKsh 帮助。开发人员可以将部件拖放到画布上,然后添加逻辑代码以使应用程序能够执行某些工作。与任何 GUI 构建器一样,代码有些冗长;但是,它是一致且可移植的。AIX 是唯一提供此功能的 UNIX 版本。
开发人员可以通过创建胶合层库来为 DtKsh 创建自己的新 API。胶合层库使 DtKsh 能够使用内置函数进行扩展,以实现系统管理和网络等功能。使用内置函数而不是调用外部命令的性能优势在于,内置函数在 shell 脚本的进程内执行。外部调用的命令必须在操作系统中创建新资源并作为单独的进程运行。DtKsh 胶合层库在普通的 UNIX C 库和 DtKsh shell 之间传递参数,并返回成功或失败状态。以下列表提供了一些创建胶合层的规则
使用 b_ 前缀命名函数。
函数返回 0 整数表示成功,返回 1 到 255 表示失败。
函数应将 argc 和 argv 作为输入。
共享链接您的胶合层库。
清单 3 显示了一个 DtKsh shell 脚本,该脚本动态加载 “example” 共享胶合层库。加载胶合层库并定义新的内置 API 后,脚本可以使用参数直接调用新的内置函数。在清单 3 中,示例内置函数使用 “Hello World” 参数调用。
通过提供内联内置函数,我们可以更快地运行脚本,因为我们不依赖于作为单独的系统进程运行的外部程序。清单 4 显示了示例内置共享库的 C 胶合层。按照上面概述的规则,我们使用 b_ 作为示例函数的前缀,并传入参数向量及其大小。函数完成其工作后,我们返回 0 表示成功,返回正整数表示失败。DtKsh 内置函数也可以充当过程,通过其参数列表传入和传出环境变量。有关如何从内置过程传递和检索环境变量的更多详细信息,请参阅 J. Stephen Pendergrast, Jr. 的 Desktop KornShell Graphical Programming [Addison-Wesley, 1995]。
