内容


扩展 SMIT 应用

Comments

引言

在前一篇 developerWorks 文章 SMIT 简介(请参见参考资料)中,您了解了 AIX® 系统管理界面工具 (SMIT) 如何能够简化 AIX 系统管理的几乎每个方面。本文向您介绍如何扩展 SMIT 以执行更多任务。通过扩展 SMIT,您可以添加还未定义的日常任务,更改现有任务,或者为您的操作员团队添加任务,这些任务在其他情况下将需要系统程序员完成。

让我们首先回顾一下 SMIT 的一些内部细节。执行系统的 SMIT 应用程序开发会负面地影响系统。最好创建您自己的开发环境、构造您自己的扩展、测试它,并最终将其添加到系统的 SMIT。

注意:本文的示例是在运行 AIX 5L™ Version 5.2 的 RS/6000® 系统上开发的。命令示例使用了 Korn Shell。

SMIT 术语和概念

在您开始之前,务必了解 SMIT 应用程序的术语和底层结构。在实际开始编程之前,请了解以下简要概述:

SMIT 和字符版本的 smitty(或 smit -c)由三种屏幕类型组成:

  • 菜单——此屏幕类型提供到其他菜单、对话框或直接到任务的选项。
  • 对话框——此屏幕类型显示执行任务所需的数据输入字段。
  • 选择器——此屏幕类型收集对话框所需的数据以运行某项特定任务。

第四个屏幕是命令状态 屏幕,它显示命令、命令的输出和状态。此屏幕是预定义的屏幕。

这些屏幕由屏幕对象定义,屏幕对象存储在 SMIT 的数据库中。对象数据管理器(Object Data Manager,ODM)用于操作该数据库中的屏幕对象。若要扩展 SMIT,需要创建一组屏幕对象,并将它们添加到 SMIT 数据库。屏幕对象在称为节 (stanza) 的 ASCII 文件中定义。节被添加到 SMIT 数据库中,并使用各种各样的 ODM 命令对其进行进一步的操作。

ODM 数据库文件驻留在对象存储库中。SMIT ODM 对象存储库为 /usr/lib/objrepos。文件由 root、group system 和 mode 664 所有。除了 SMIT 以外,系统 ODM 数据库还管理设备配置、用于安装和更新过程的产品数据、通信配置信息和系统资源信息。对系统 ODM 数据库进行更改可能会导致系统出现问题。因此,强烈建议使用 SMIT ODM 数据库的副本来进行开发和初始测试,并使用非 root、非 group system 用户。最终测试和安装将需要 root 权限。另外还强烈建议您在对系统存储库作出任何更改之前对其进行备份。我将提供一些关于如何在将更改添加到系统对象存储库之前备份该存储库的示例。

环境变量 ODMDIR 指定 ODM 实用程序的 ODM 对象存储库。缺省 ODMDIR 为 /etc/objrepos。在开发期间,请将 ODMDIR 设置为指向您的开发对象存储库。SMIT 使用 /usr/lib/objrepos 作为其存储库,除非在命令行上使用 -o 标志来指定不同的路径。

ODM 对象划分为对象类。同一对象类的对象定义存储在同一个对象存储库文件中。某个类的对象存储库文件名称与该类名称相同。使用以下命令来查看一下您系统上正在使用的各种对象类:$ ls -l /usr/lib/objrepos

SMIT 使用以下对象类:

  • sm_menu_opt
  • sm_name_hdr
  • sm_cmd_hdr
  • sm_cmd_opt

表 1 显示了用于定义每种屏幕类型的对象。稍后的示例将显示这些对象如何组合起来形成 SMIT 命令。

表 1. 用于定义每种屏幕类型的对象类
屏幕类型对象类对象用途(典型情况)
菜单sm_menu_opt1 表示屏幕标题
sm_menu_opt1 表示第一项
sm_menu_opt1 表示第二项
......
sm_menu_opt1 表示最后一项
选择器sm_name_hdr1 表示屏幕标题和其他属性
sm_cmd_opt1 表示输入字段或弹出列表
对话框sm_cmd_hdr1 表示屏幕标题和命令字符串
sm_cmd_opt1 表示第一个输入字段
sm_cmd_opt1 表示第二个输入字段
......
sm_cmd_opt1 表示最后一个输入字段

下面让我们看一下对象是如何构造的,以及它们如何在您调用 SMIT 时组合在一起。

创建开发环境

在扩展 SMIT 之前,您必须首先创建一个开发环境。您不会希望因为在系统对象存储库中开发 SMIT 扩展而对系统造成负面影响。您可以在完成开发和测试之后容易地将更改添加到系统对象存储库。在理想的情况下,您应该还有一个可以完成此任务的开发系统,而不是影响生产环境。

创建或获得一个不属于系统组成员的用户帐户。登录该帐户并发出以下命令,如清单 1 所示。

清单 1. 创建 SMIT 对象存储库的副本
$ mkdir objrepos
$ cp /usr/lib/objrepos/sm* ./objrepos
$ ODMDIR=~/objrepos export ODMDIR

您还可能希望在此项目期间将 ODMDIR 分配添加到 .profile。否则,您需要记住在每次登录以处理此项目时重新分配 ODMDIR

熟悉 SMIT 对象类型

现在让我们看一下屏幕定义,以及 SMIT 中已经定义的内容(请参见清单 2)。您应该能够看到这些定义如何与您在使用 SMIT 时所看到的内容相互关联。

清单 2. SMIT 对象的结构
$ odmshow sm_menu_opt

class sm_menu_opt {
        char id_seq_num[17];       /* offset: 0xc ( 12) */
        char id[65];               /* offset: 0x1d ( 29) */
        char next_id[65];          /* offset: 0x5e ( 94) */
        vchar text[1025];          /* offset: 0xa0 ( 160) */
        vchar text_msg_file[1025]; /* offset: 0xa4 ( 164) */
        long text_msg_set;         /* offset: 0xa8 ( 168) */
        long text_msg_id;          /* offset: 0xac ( 172) */
        char next_type[2];         /* offset: 0xb0 ( 176) */
        char alias[2];             /* offset: 0xb2 ( 178) */
        char help_msg_id[17];      /* offset: 0xb4 ( 180) */
        vchar help_msg_loc[1025];  /* offset: 0xc8 ( 200) */
        vchar help_msg_base[64];   /* offset: 0xcc ( 204) */
        vchar help_msg_book[64];   /* offset: 0xd0 ( 208) */
        };
/*
        descriptors:    13
        structure size:     0xd4 (212) bytes
        data offset:    0x200032f0
        population:     1750 objects (1749 active, 1 deleted)
*/

清单 2 看起来类似于 C 程序设计中的结构定义。继续看一下 sm_cmd_hdr, sm_cmd_opt, 和 sm_name_hdr

下一步,将已经定义的屏幕对象定义提取到文本文件中,如清单 3 所示。

清单 3. 将已定义的屏幕对象定义提取到文本文件中
$ odmget sm_menu_opt > sm_menu_opt.get
$ odmget sm_cmd_hdr > sm_cmd_hdr.get
$ odmget sm_cmd_opt > sm_cmd_opt.get
$ odmget sm_name_hdr > sm_name_hdr.get

除了更容易滚动和提取对象定义外,它还允许您查找特定字段,以确保没有重复“next_id”或选择器“id”字段,这两个字段必须是唯一的。

滚动查阅 sm_menu_opt.get。请注意以下事项:

  • 屏幕定义由空白行分隔。这是它们的分隔方式,也是您需要构造自己的节 (stanza) 的方式。odmget 的输出格式与 odmadd 使用的格式相同,从理论上讲,您可以对 SMIT 中的所有条目执行 odmdelete 操作,并使用这些文本文件来完全重新创建它。
  • text 是选择器按钮旁边或 smitty 菜单页上出现的内容。
  • next_id 是您在执行该项时所调用的对象。“__ROOT__”id 包含“top_menu”的“next_id”。所有 id =“top_menu”的条目都会显示出来,其中:
    • “next_type” = 下一个对象的类型
    • “m” = 菜单
    • “d” = 对话框
    • “n” = 选择器弹出列表
    • “i” = 信息
  • 不同屏幕定义的“id”字段是相同的。具有相同 ID 字段的定义出现在相同菜单上。请注意其 ID 为“top_menu”的对象。这些对象全都在您启动 smit(或 smitty)时出现的第一个菜单上。它们的出现顺序由 id_seq_num 设定。id_seq_num 值不一定是连续的;IBM 在它们之间预留了一些空白,您可以在菜单中自然地插入自己的对象,而不必重新定义该菜单上的所有对象。

查看一下 sm_cmd_hdr.get,并注意 cmd_to_exec。有些是简单的命令,其他则是复杂的 Shell 脚本。当 odmget 提取脚本时,它使用“\”对“特殊”字符进行转义。您的自定义代码不需要包括这些转义,但是您应该预想到 odmget 也会将它们添加到您的代码。

所有对象类的完整字段描述可以在“General Programming Concepts: Writing and Debugging Programs in the AIX 5L”文档中的 SMIT 部分找到(请参见参考资料)。

编程

让我们通过示例来完成相关步骤,以在您的测试对象存储库中创建 SMIT 中的一个新菜单对象。

步骤 1:您要向 SMIT 添加什么活动?

假设您经常添加和删除用户,这是一个可由操作员团队完成的任务。除了各自的用户名、用户 ID 和主目录 (/home/username) 外,这些用户全都具有相同特征。让某个操作员通过 SMIT 删除用户不成问题,因为对话框屏幕上只有两行内容。然而,“Add a User”对话框包括 49 个选择器!

图 1. 显示了前 17 个选择器的“Add a User”对话框
显示了前 17 个选择器的“Add a User”对话框
显示了前 17 个选择器的“Add a User”对话框

您需要一个菜单选项,其中只有一个针对该用户名的选择器。让系统挑选 UID,然后硬编码任何其他参数。还要更改用户的密码,以便他们能够登录(并强制他们在登录时更改各自的密码)。请注意,这只是一个示例,您或您的安全策略可能规定了其他参数,而不是这里使用的参数。

用于创建此类用户的命令行类似于清单 4

清单 4. 您希望 SMIT 能够构建和运行的命令
# mkuser  pgrp='other'  su='false' home='/home/user' shell='/usr/bin/ksh' user
# passwd user

步骤 2:SMIT 中是否已经存在任何相近的内容?

一切都从头开始是没有意义的。在此例中,您知道“Add a User”对话框与您需要的内容非常相近。从“text”字段为“Add a User”的 sm_menu_opt.get 文件提取屏幕定义,或者使用 odmget -q "text = 'Add a User'" sm_menu_opt(请参见清单 5)。

清单 5. 从 sm_menu_opt.get 文件提取屏幕定义
sm_menu_opt:
        id_seq_num = "010"
        id = "users"
        next_id = "mkuser"
        text = "Add a User"
        text_msg_file = "smit.cat"
        text_msg_set = 25
        text_msg_id = 166
        next_type = "d"
        alias = ""
        help_msg_id = "1800168"
        help_msg_loc = ""
        help_msg_base = ""
        help_msg_book = ""

您看到 next_type 为“d”(对话框),并且 next_id 为“mkuser”。运行 odmget -q "id = mkuser" sm_cmd_hdr(请参见清单 6)。

清单 6. 从 sm_cmd_hdr 提取屏幕定义
sm_cmd_hdr:
        id = "mkuser"
        option_id = "user_add"
        has_name_select = "n"
        name = "Add a User"
        name_msg_file = "smit.cat"
        name_msg_set = 25
        name_msg_id = 166
        cmd_to_exec = "x() {\n\
LIST=\n\
SET_A=\n\
for i in \"$@\"\n\
do\n\
        if [ \"$i\" = \"admin=true\" ]\n\
        then\n\
                SET_A=\"-a\"\n\
                continue\n\
        fi\n\
        LIST=\"$LIST \\\"$i\\\"\"\n\
done\n\
eval mkuser $SET_A $LIST\n\
}\n\
x"
        ask = "n"
        exec_mode = ""
        ghost = "n"
        cmd_to_discover = "lsuser -D"
        cmd_to_discover_postfix = ""
        name_size = 0
        value_size = 0
        help_msg_id = "1800168"
        help_msg_loc = ""
        help_msg_base = ""
        help_msg_book = ""

您看到“option_id” = “user_add”。grep user_add sm_cmd_opt.get 显示了 49 个条目,此菜单项的每个选择器分别对应一个条目。您只需要提示指定用户名的那一个条目(请参见清单 7)。

清单 7. 从 sm_cmd_opt 文件提取命令定义
sm_cmd_opt:
        id_seq_num = "01"
        id = "user_add"
        disc_field_name = "_rawname"
        name = "User NAME"
        name_msg_file = "smit.cat"
        name_msg_set = 3
        name_msg_id = 3
        op_type = ""
        entry_type = "t"
        entry_size = 0
        required = "+"
        prefix = "--"
        cmd_to_list_mode = ""
        cmd_to_list = ""
        cmd_to_list_postfix = ""
        multi_select = "n"
        value_index = 0
        disp_values = ""
        values_msg_file = ""
        values_msg_set = 0
        values_msg_id = 0
        aix_values = ""

将这些定义放在一个文件中。这是您用于添加自己的对象的节 (stanza) 文件。通过在行首使用“#”或在赋值号之后使用“*”,您可以向节文件添加注释。确保节文件中只有空白行分隔屏幕定义。

步骤 3:进行修改

您不需要包括每个字段定义。Odmadd 会应用缺省值(通常为“”或 0)。

下面是您为了创建自己的 SMIT 屏幕和命令而需要对这些对象定义所做的更改:

  • sm_menu_opt:
    • ID 保持相同。
    • seq_num 需要更改。让我们首先显示您的命令,因此将其更改为“5”。
    • next_id 需要指定您的下一个脚本,因此我们将其命名为“mkuser2”。
    • Text 需要将这个命令与其他命令区分开来,例如“Add a Simple User”。
    • next_type 保持相同。
    • Alias 可以保持不变。
    • 其余行可以删除。它们与用于提供帮助信息的 Message Facility 相关联,这些内容超出了本文的范围。
  • Sm_cmd_hdr:
    • ID 需要与上面调用的 ID 匹配并保持唯一,例如“mkuser2”。使用 grep mkuser2 *.get 来验证唯一性。
    • option_add:需要指定另一个名称,例如“user-add2”,否则您将获得所有 49 个条目。
    • name:“Add a Simple User”。
    • has_name_select 可以保留为“n”,意味着您可以通过快速路经直接访问它。
    • Msg 可以删除。
    • cmd_to_exec:这是所执行的命令。您需要硬编码除用户名以外的选项,添加用于检查 mkuser 命令是否成功完成的代码,然后更改用户的密码。不必关注 odmget 显示的所有“\”转义。您不需要在自己的代码中包括它们,因为它们会在您执行另一个 odmget 时出现。将“LIST”行更改为:LIST="pgrp=other su=false home=/home/$i shell=/usr/bin/ksh"。在“eval”行后面,添加清单 8 中的内容。
      清单 8. 向您的 SMIT 应用程序添加“Changing Password”所需要的 Korn Shell
      # test for success, then change the password
      if [[ $? = 0 ]]
      then
              passwd $i
      fi
  • sm_cmd_opt:
    • id:需要更改为 match sm_cmd_hdr.option_add。“user-add2”。

另外,还要注意 required = "+"。这会在您的选择框旁边显示一个“+”,指示需要某个条目才能继续。

步骤 4:安装和测试

当您对自己的节文件感到满意时,请将其添加到您的开发对象存储库。再次确保您不是 root 用户并且 ODMDIR 指向您的测试目录(请参见清单 9)。

清单 9. 检查您的身份和 ODMDIR 分配,然后将节文件添加到您的开发对象存储库
$ id
uid=101(monroe) gid=3(sys) groups=4(adm)
$ echo $ODMDIR
/home/monroe/objrepos

将您的节文件添加到对象存储库: $ odmadd stanza1.

然后使用 odmget 来提取各个对象,从而验证它们是否已经安装(请参见清单 10)。

清单 10. 使用 odmget 提取各个对象
$ odmget -q "next_id = mkuser2" sm_menu_opt
$ odmget -q "id = mkuser2" sm_cmd_hdr
$ odmget -q "id = "user_add2"

通过调用 SMIT 来进行测试,并且不指定执行和开发存储库:$ smit -x -o $ODMDIR。向下浏览至 Security & Users > Users。请注意,您有了一个新条目——“Add a Simple User”(请参见图 2)。

图 2. 您的新条目——“Add a Simple User”
新条目——“Add a Simple User”。
新条目——“Add a Simple User”。

您的 sm_menu_opt 屏幕定义能够正常工作。选择“Add a Simple User”(请参见图 3)。

图 3. 选择“Add a Simple User”
选择“Add a Simple User”
选择“Add a Simple User”

这就是您开发的命令屏幕;它具有正确的屏幕标题,并且对话框中只有一个选择器。添加任何用户名并按 Enter。由于您不是 root 用户(并且没有指定执行标志),该命令不会运行;它只是将所要做的工作追加到 smit.script 文件(请参见清单 11)。

清单 11. SMIT 将该命令的代码正确地写入 smit.script
#
#     [Dec 04 2006, 14:28:05]
#
x() {
LIST=pgrp=other su=false home=/home/$i shell=/usr/bin/ksh
SET_A=
for i in "$@"
do
        if [ "$i" = "admin=true" ]
        then
                SET_A="-a"
                continue
        fi
        LIST="$LIST \"$i\""
done
eval mkuser $SET_A $LIST
if [ "$?" = "0" ]
then
        passwd "$i"
fi
}
x bozo

看起来非常好。现在让我们作为 root 用户进行试验,并实际创建一个帐户(请参见清单 12)。

清单 12. 通过作为 root 用户实际创建一个帐户来测试您的扩展
$ su
# export ODMDIR=./objrepos
# smit -o $ODMDIR

继续使用您的扩展添加一个用户。请注意,系统将提示您输入用户的密码。继续并提供密码(请参见图 4)。

图 4. 显示您的 SMIT 扩展成功执行的命令状态屏幕
提示输入用户的密码
提示输入用户的密码

返回到“Change/Show Characteristics of a User”并显示您刚才创建的用户(请参见图 5)。

图 5. Change/Show Characteristics of a User
返回到 Change/Show Characteristics of a User
返回到 Change/Show Characteristics of a User

如果您希望作出进一步的修改,可以更改节文件并再次运行 odmadd。它将改写您前面添加的条目。确保对您的更改进行全面测试。

当您完成测试时,删除您在系统上创建的测试用户帐户。

安装到生产环境中

切换到 root 用户并相应设置 ODMDIR 变量以反映 SMIT 的系统数据库(请参见清单 13)。

清单 13. 设置 ODMDIR 变量以反映 SMIT 的系统数据库
$ su
# export ODMDIR=/usr/lib/objrepos

SMIT 数据库存储库在 /usr/lib/objrepos 中。强烈建议您在执行最终安装之前备份该存储库。清单 14 显示了一种方法。

清单 14. 备份 SMIT 数据库存储库
# cd /usr/lib
# tar cvf objrepos.tar objrepos

这将创建 /usr/lib/objrepos 目录的 tar 存档,当您需要还原时可容易地从中恢复。

将您的节文件所定义的屏幕对象添加到系统对象存储库:运行 # odmadd stanza 并使用“smit”(无选项)再次进行测试。让另一位管理员试验您的更改。当您感到满意时,可以删除所创建的任何测试帐户。

最后,对您所做的更改作文档记录,并保存您的节文件。如果某个将来的 AIX 发行版更新了 SMIT 对象存储库,您的更改可能会丢失,并需要重新安装文件。

总结

现在您已经成功扩展了 SMIT。您了解了如何安全地开发、测试和安装扩展。您掌握了 SMIT 对象类、它们的结构以及它们如何组合在一起的初步知识。您可以修改已经存在的屏幕定义,以使 SMIT 按您的希望进行工作。通过开发更多扩展,您可以更好地了解对象类。

存在各种各样必须经常完成的任务,通过创建 SMIT 扩展可以加速或简化这些任务。通过按照 Programming Concepts Guide 的描述来创建此类扩展并添加 SMIT 帮助信息,您可以让管理员腾出时间来做其他工作。


相关主题


评论

添加或订阅评论,请先登录注册

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=AIX and UNIX
ArticleID=201158
ArticleTitle=扩展 SMIT 应用
publish-date=03082007