JavaScript is required to for searching.
跳过导航链接
退出打印视图
Oracle® ZFS Storage Appliance 管理指南
Oracle 技术网
文档库
PDF
打印视图
反馈
search filter icon
search icon

文档信息

使用本文档

 1 Oracle ZFS Storage Appliance 概述

 2 状态

 3 初始配置

 4 网络配置

 5 存储配置

 6 存储区域网络配置

 7 用户配置

 8 设置 ZFSSA 首选项

 9 警报配置

 10 群集配置

 11 ZFSSA 服务

 12 共享资源、项目和模式

 13 复制

 14 影子迁移

 15 CLI 脚本化

自动化访问

批处理命令

脚本化命令

脚本环境

与系统交互

Run 函数

Get 函数

List 函数

Children 函数

Choices 函数

生成输出

处理错误

 16 维护工作流

 17 集成

索引

与系统交互

当然,除非可以与整个系统交互,否则脚本的用处不大。下面是一些允许脚本与系统交互的内置函数:

表 15-1  支持系统交互的内置函数
函数
说明
get
获取指定的属性的值。请注意,此函数以原生格式返回值,例如将日期作为 Date 对象返回。
list
返回对应于当前上下文动态子代的标记数组。
run
运行 Shell 中指定的命令,并将所有输出作为字符串返回。请注意,如果输出包含多行,则返回的字符串将包含嵌入的换行符。
props
返回当前节点的属性名称数组。
set
采用两个字符串参数,将指定的属性设置为指定的值。
choicies
返回一组值已知且可枚举的任何属性的有效属性值数组。

Run 函数

脚本与较大系统交互的最简单方式就是使用 "run" 函数:它获取要运行的命令,并将该命令的输出作为字符串返回。例如:

dory:> configuration version script dump(run('get boot_time'))
'                     boot_time = 2009-10-12 07:02:17\n'

内置的 dump 函数转储参数,但不展开任何嵌入的换行符。ECMAScript 的字符串处理工具可用于拆分输出。例如,按空格拆分上面的结果:

dory:> configuration version script dump(run('get boot_time').split(/\s+/))
['', 'boot_time', '=', '2009-10-12', '07:02:17', '']

Get 函数

run 函数非常强大,它往往专门依靠解析输出来获取有关系统的信息-但是这显然存在缺陷,因为它让脚本解析用户可读的输出,输出在将来可能会发生更改,也可能不会。要更稳妥地收集有关系统的信息,请使用内置的 "get" 函数。对于 boot_time 属性,此函数返回的内容不是字符串,而是 ECMAScript Date 对象,以允许通过编程方式处理属性值。例如,您可能希望结合使用 boot_time 属性和当前时间确定自引导以来经过的时间:

script
       run('configuration version');
       now = new Date();
       uptime = (now.valueOf() - get('boot_time').valueOf()) / 1000; 
       printf('up %d day%s, %d hour%s, %d minute%s, %d second%s\n',
           d = uptime / 86400, d < 1 || d >= 2 ? 's' : '',
           h = (uptime / 3600) % 24, h < 1 || h >= 2 ? 's': '',
           m = (uptime / 60) % 60, m < 1 || m >= 2 ? 's': '',
           s = uptime % 60, s < 1 || s >= 2 ? 's': '');

假设上面的内容保存为 "uptime.aksh",则可以通过以下方式运行:

% ssh root@dory < uptime.aksh
Pseudo-terminal will not be allocated because stdin is not a terminal.
Password: 
up 2 days, 10 hours, 47 minutes, 48 seconds

由于是 ssh 客户机,因此会出现有关伪终端分配的消息;该消息所指的问题可以通过为 ssh 指定 "-T" 选项进行处理。

List 函数

在具有动态子代的上下文中,以编程方式迭代这些子代可能非常有用。这可以使用 list 函数实现,该函数返回动态子代数组。例如,下面是迭代每个项目中每个共享资源的脚本,输出所用空间和可用空间:

script
       run('shares');
       projects = list();

       for (i = 0; i < projects.length; i++) {
               run('select ' + projects[i]);
               shares = list();

               for (j = 0; j < shares.length; j++) {
                       run('select ' + shares[j]);
                       printf("%s/%s %1.64g %1.64g\n", projects[i], shares[j],
                           get('space_data'), get('space_available'));
                       run('cd ..');
               }

               run('cd ..');
       }

下面是运行该脚本的输出(假设将其保存到名为 "space.aksh" 的文件中):

% ssh root@koi < space.aksh
Password: 
admin/accounts 18432 266617007104
admin/exports 18432 266617007104
admin/primary 18432 266617007104
admin/traffic 18432 266617007104
admin/workflow 18432 266617007104
aleventhal/hw_eng 18432 266617007104
bcantrill/analytx 1073964032 266617007104
bgregg/dashbd 18432 266617007104
bgregg/filesys01 26112 107374156288
bpijewski/access_ctrl 18432 266617007104
...

如果有人希望获得以上结果的 "易于阅读"(虽然通过编程方式比较难处理)版本,则可以直接解析 get 命令的输出:

script
       run('shares');
       projects = list();

       printf('%-40s %-10s %-10s\n', 'SHARE', 'USED', 'AVAILABLE');

       for (i = 0; i < projects.length; i++) {
               run('select ' + projects[i]);
               shares = list();

               for (j = 0; j < shares.length; j++) {
                       run('select ' + shares[j]);

                       share = projects[i] + '/' + shares[j];
                       used = run('get space_data').split(/\s+/)[3];
                       avail = run('get space_available').split(/\s+/)[3];

                       printf('%-40s %-10s %-10s\n', share, used, avail);
                       run('cd ..');
               }

               run('cd ..');
       }

以下是运行该新脚本的部分输出(假设将其命名为 "prettyspace.aksh"):

% ssh root@koi < prettyspace.aksh
Password:
SHARE                                    USED       AVAILABLE 
admin/accounts                           18K        248G      
admin/exports                            18K        248G      
admin/primary                            18K        248G      
admin/traffic                            18K        248G      
admin/workflow                           18K        248G      
aleventhal/hw_eng                        18K        248G      
bcantrill/analytx                        1.00G      248G      
bgregg/dashbd                            18K        248G       
bgregg/filesys01                         25.5K      100G      
bpijewski/access_ctrl                    18K        248G      
...

Children 函数

即使是在具有静态子代的上下文中,以编程方式迭代这些子代同样非常有用。这可以使用 children 函数实现,该函数返回静态子代数组。例如,下面是迭代每个服务的脚本,输出服务的状态:

configuration services
script
       var svcs = children();
       for (var i = 0; i < svcs.length; ++i) {
                run(svcs[i]);
                try {
                        printf("%-10s %s\n", svcs[i], get('<status>'));
                } catch (err) { }
                run("done");
       }

下面是运行该脚本的输出(假设将其保存到名为 "svcinfo.aksh" 的文件中):

% ssh root@koi < space.aksh
Password: 
cifs       disabled
dns        online
ftp        disabled
http       disabled
identity   online
idmap      online
ipmp       online
iscsi      online
ldap       disabled
ndmp       online
nfs        online
nis        online
ntp        online
scrk       online
sftp       disabled
smtp       online
snmp       disabled
ssh        online
tags       online
vscan      disabled

Choices 函数

Choices 函数将返回一组值已知且可枚举的任何属性的有效属性值数组。例如,以下脚本将使用 choices 函数检索共享资源节点上所有池的列表,然后迭代所有池来列出项目和共享资源以及可用空间。

fmt = '%-40s %-15s %-15s\n';
printf(fmt, 'SHARE', 'USED', 'AVAILABLE');
run('cd /');
run('shares');
pools = choices('pool');
for (p = 0; p < pools.length; p++) {
        set('pool', pools[p]);
        projects = list();
        for (i = 0; i < projects.length; i++) {
                run('select ' + projects[i]);
                shares = list();
                for (j = 0; j < shares.length; j++) {
                        run('select ' + shares[j]);
                        share = pools[p] + ':' + projects[i] + '/' + shares[j];
                        printf(fmt, share, get('space_data'),
                            get('space_available'));
                        run('cd ..');
                }
                run('cd ..');
        }
}

以下是运行该脚本的输出:

SHARE                                    USED            AVAILABLE     
pond:projectA/fs1                        31744           566196178944  
pond:projectA/fs2                        31744           566196178944  
pond:projectB/lun1                       21474836480     587670999040  
puddle:deptA/share1                      238475          467539219283
puddle:deptB/share1                      129564          467539219283
puddle:deptB/share2                      19283747        467539219283